HDFS-6304. Merge r1591411 from trunk.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1591412 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Haohui Mai 2014-04-30 17:45:57 +00:00
parent a85a2a9a0a
commit 915b7bc3a6
9 changed files with 120 additions and 101 deletions

View File

@ -80,6 +80,9 @@ Release 2.5.0 - UNRELEASED
HDFS-6269. NameNode Audit Log should differentiate between webHDFS open and HDFS-6269. NameNode Audit Log should differentiate between webHDFS open and
HDFS open. (Eric Payne via jeagles) HDFS open. (Eric Payne via jeagles)
HDFS-6304. Consolidate the logic of path resolution in FSDirectory.
(wheat9)
OPTIMIZATIONS OPTIMIZATIONS
HDFS-6214. Webhdfs has poor throughput for files >2GB (daryn) HDFS-6214. Webhdfs has poor throughput for files >2GB (daryn)

View File

@ -516,7 +516,7 @@ boolean unprotectedRemoveBlock(String path,
} }
// update space consumed // update space consumed
final INodesInPath iip = rootDir.getINodesInPath4Write(path, true); final INodesInPath iip = getINodesInPath4Write(path, true);
updateCount(iip, 0, -fileNode.getBlockDiskspace(), true); updateCount(iip, 0, -fileNode.getBlockDiskspace(), true);
return true; return true;
} }
@ -588,7 +588,7 @@ boolean unprotectedRenameTo(String src, String dst, long timestamp)
throws QuotaExceededException, UnresolvedLinkException, throws QuotaExceededException, UnresolvedLinkException,
FileAlreadyExistsException, SnapshotAccessControlException, IOException { FileAlreadyExistsException, SnapshotAccessControlException, IOException {
assert hasWriteLock(); assert hasWriteLock();
INodesInPath srcIIP = rootDir.getINodesInPath4Write(src, false); INodesInPath srcIIP = getINodesInPath4Write(src, false);
final INode srcInode = srcIIP.getLastINode(); final INode srcInode = srcIIP.getLastINode();
// check the validation of the source // check the validation of the source
@ -814,7 +814,7 @@ boolean unprotectedRenameTo(String src, String dst, long timestamp,
} }
} }
String error = null; String error = null;
final INodesInPath srcIIP = rootDir.getINodesInPath4Write(src, false); final INodesInPath srcIIP = getINodesInPath4Write(src, false);
final INode srcInode = srcIIP.getLastINode(); final INode srcInode = srcIIP.getLastINode();
// validate source // validate source
if (srcInode == null) { if (srcInode == null) {
@ -852,7 +852,7 @@ boolean unprotectedRenameTo(String src, String dst, long timestamp,
+ error); + error);
throw new IOException(error); throw new IOException(error);
} }
INodesInPath dstIIP = rootDir.getINodesInPath4Write(dst, false); INodesInPath dstIIP = getINodesInPath4Write(dst, false);
if (dstIIP.getINodes().length == 1) { if (dstIIP.getINodes().length == 1) {
error = "rename destination cannot be the root"; error = "rename destination cannot be the root";
NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: " NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
@ -957,7 +957,7 @@ boolean unprotectedRenameTo(String src, String dst, long timestamp,
// src and dst file/dir are in the same directory, and the dstParent has // src and dst file/dir are in the same directory, and the dstParent has
// been replaced when we removed the src. Refresh the dstIIP and // been replaced when we removed the src. Refresh the dstIIP and
// dstParent. // dstParent.
dstIIP = rootDir.getINodesInPath4Write(dst, false); dstIIP = getINodesInPath4Write(dst, false);
} }
boolean undoRemoveDst = false; boolean undoRemoveDst = false;
@ -1114,7 +1114,7 @@ Block[] unprotectedSetReplication(String src, short replication,
UnresolvedLinkException, SnapshotAccessControlException { UnresolvedLinkException, SnapshotAccessControlException {
assert hasWriteLock(); assert hasWriteLock();
final INodesInPath iip = rootDir.getINodesInPath4Write(src, true); final INodesInPath iip = getINodesInPath4Write(src, true);
final INode inode = iip.getLastINode(); final INode inode = iip.getLastINode();
if (inode == null || !inode.isFile()) { if (inode == null || !inode.isFile()) {
return null; return null;
@ -1155,7 +1155,7 @@ long getPreferredBlockSize(String path) throws UnresolvedLinkException,
FileNotFoundException, IOException { FileNotFoundException, IOException {
readLock(); readLock();
try { try {
return INodeFile.valueOf(rootDir.getNode(path, false), path return INodeFile.valueOf(getNode(path, false), path
).getPreferredBlockSize(); ).getPreferredBlockSize();
} finally { } finally {
readUnlock(); readUnlock();
@ -1166,7 +1166,7 @@ boolean exists(String src) throws UnresolvedLinkException {
src = normalizePath(src); src = normalizePath(src);
readLock(); readLock();
try { try {
INode inode = rootDir.getNode(src, false); INode inode = getNode(src, false);
if (inode == null) { if (inode == null) {
return false; return false;
} }
@ -1192,7 +1192,7 @@ void unprotectedSetPermission(String src, FsPermission permissions)
throws FileNotFoundException, UnresolvedLinkException, throws FileNotFoundException, UnresolvedLinkException,
QuotaExceededException, SnapshotAccessControlException { QuotaExceededException, SnapshotAccessControlException {
assert hasWriteLock(); assert hasWriteLock();
final INodesInPath inodesInPath = rootDir.getINodesInPath4Write(src, true); final INodesInPath inodesInPath = 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);
@ -1217,7 +1217,7 @@ void unprotectedSetOwner(String src, String username, String groupname)
throws FileNotFoundException, UnresolvedLinkException, throws FileNotFoundException, UnresolvedLinkException,
QuotaExceededException, SnapshotAccessControlException { QuotaExceededException, SnapshotAccessControlException {
assert hasWriteLock(); assert hasWriteLock();
final INodesInPath inodesInPath = rootDir.getINodesInPath4Write(src, true); final INodesInPath inodesInPath = 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);
@ -1264,7 +1264,7 @@ void unprotectedConcat(String target, String [] srcs, long timestamp)
} }
// do the move // do the move
final INodesInPath trgIIP = rootDir.getINodesInPath4Write(target, true); final INodesInPath trgIIP = getINodesInPath4Write(target, true);
final INode[] trgINodes = trgIIP.getINodes(); final INode[] trgINodes = trgIIP.getINodes();
final INodeFile trgInode = trgIIP.getLastINode().asFile(); final INodeFile trgInode = trgIIP.getLastINode().asFile();
INodeDirectory trgParent = trgINodes[trgINodes.length-2].asDirectory(); INodeDirectory trgParent = trgINodes[trgINodes.length-2].asDirectory();
@ -1333,7 +1333,7 @@ boolean delete(String src, BlocksMapUpdateInfo collectedBlocks,
final long filesRemoved; final long filesRemoved;
writeLock(); writeLock();
try { try {
final INodesInPath inodesInPath = rootDir.getINodesInPath4Write( final INodesInPath inodesInPath = getINodesInPath4Write(
normalizePath(src), false); normalizePath(src), false);
if (!deleteAllowed(inodesInPath, src) ) { if (!deleteAllowed(inodesInPath, src) ) {
filesRemoved = -1; filesRemoved = -1;
@ -1383,7 +1383,7 @@ private static boolean deleteAllowed(final INodesInPath iip,
boolean isNonEmptyDirectory(String path) throws UnresolvedLinkException { boolean isNonEmptyDirectory(String path) throws UnresolvedLinkException {
readLock(); readLock();
try { try {
final INodesInPath inodesInPath = rootDir.getLastINodeInPath(path, false); final INodesInPath inodesInPath = 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
@ -1412,7 +1412,7 @@ void unprotectedDelete(String src, long mtime) throws UnresolvedLinkException,
BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo(); BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo();
List<INode> removedINodes = new ChunkedArrayList<INode>(); List<INode> removedINodes = new ChunkedArrayList<INode>();
final INodesInPath inodesInPath = rootDir.getINodesInPath4Write( final INodesInPath inodesInPath = getINodesInPath4Write(
normalizePath(src), false); normalizePath(src), false);
long filesRemoved = -1; long filesRemoved = -1;
if (deleteAllowed(inodesInPath, src)) { if (deleteAllowed(inodesInPath, src)) {
@ -1537,7 +1537,7 @@ DirectoryListing getListing(String src, byte[] startAfter,
if (srcs.endsWith(HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR)) { if (srcs.endsWith(HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR)) {
return getSnapshotsListing(srcs, startAfter); return getSnapshotsListing(srcs, startAfter);
} }
final INodesInPath inodesInPath = rootDir.getLastINodeInPath(srcs, true); final INodesInPath inodesInPath = getLastINodeInPath(srcs, true);
final int snapshot = inodesInPath.getPathSnapshotId(); final int snapshot = inodesInPath.getPathSnapshotId();
final INode targetNode = inodesInPath.getINode(0); final INode targetNode = inodesInPath.getINode(0);
if (targetNode == null) if (targetNode == null)
@ -1627,7 +1627,7 @@ HdfsFileStatus getFileInfo(String src, boolean resolveLink)
if (srcs.endsWith(HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR)) { if (srcs.endsWith(HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR)) {
return getFileInfo4DotSnapshot(srcs); return getFileInfo4DotSnapshot(srcs);
} }
final INodesInPath inodesInPath = rootDir.getLastINodeInPath(srcs, resolveLink); final INodesInPath inodesInPath = 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.getPathSnapshotId()); inodesInPath.getPathSnapshotId());
@ -1676,7 +1676,7 @@ Block[] getFileBlocks(String src) throws UnresolvedLinkException {
waitForReady(); waitForReady();
readLock(); readLock();
try { try {
final INode i = rootDir.getNode(src, false); final INode i = getNode(src, false);
return i != null && i.isFile()? i.asFile().getBlocks(): null; return i != null && i.isFile()? i.asFile().getBlocks(): null;
} finally { } finally {
readUnlock(); readUnlock();
@ -1703,7 +1703,7 @@ public INodesInPath getLastINodeInPath(String src)
throws UnresolvedLinkException { throws UnresolvedLinkException {
readLock(); readLock();
try { try {
return rootDir.getLastINodeInPath(src, true); return getLastINodeInPath(src, true);
} finally { } finally {
readUnlock(); readUnlock();
} }
@ -1716,7 +1716,7 @@ public INodesInPath getINodesInPath4Write(String src
) throws UnresolvedLinkException, SnapshotAccessControlException { ) throws UnresolvedLinkException, SnapshotAccessControlException {
readLock(); readLock();
try { try {
return rootDir.getINodesInPath4Write(src, true); return getINodesInPath4Write(src, true);
} finally { } finally {
readUnlock(); readUnlock();
} }
@ -1730,7 +1730,7 @@ public INode getINode4Write(String src) throws UnresolvedLinkException,
SnapshotAccessControlException { SnapshotAccessControlException {
readLock(); readLock();
try { try {
return rootDir.getINode4Write(src, true); return getINode4Write(src, true);
} finally { } finally {
readUnlock(); readUnlock();
} }
@ -1746,7 +1746,7 @@ boolean isValidToCreate(String src) throws UnresolvedLinkException,
readLock(); readLock();
try { try {
if (srcs.startsWith("/") && !srcs.endsWith("/") if (srcs.startsWith("/") && !srcs.endsWith("/")
&& rootDir.getINode4Write(srcs, false) == null) { && getINode4Write(srcs, false) == null) {
return true; return true;
} else { } else {
return false; return false;
@ -1763,7 +1763,7 @@ boolean isDir(String src) throws UnresolvedLinkException {
src = normalizePath(src); src = normalizePath(src);
readLock(); readLock();
try { try {
INode node = rootDir.getNode(src, false); INode node = getNode(src, false);
return node != null && node.isDirectory(); return node != null && node.isDirectory();
} finally { } finally {
readUnlock(); readUnlock();
@ -1779,7 +1779,7 @@ boolean isDirMutable(String src) throws UnresolvedLinkException,
src = normalizePath(src); src = normalizePath(src);
readLock(); readLock();
try { try {
INode node = rootDir.getINode4Write(src, false); INode node = getINode4Write(src, false);
return node != null && node.isDirectory(); return node != null && node.isDirectory();
} finally { } finally {
readUnlock(); readUnlock();
@ -1800,7 +1800,7 @@ void updateSpaceConsumed(String path, long nsDelta, long dsDelta)
UnresolvedLinkException, SnapshotAccessControlException { UnresolvedLinkException, SnapshotAccessControlException {
writeLock(); writeLock();
try { try {
final INodesInPath iip = rootDir.getINodesInPath4Write(path, false); final INodesInPath iip = getINodesInPath4Write(path, false);
if (iip.getLastINode() == null) { if (iip.getLastINode() == null) {
throw new FileNotFoundException("Path not found: " + path); throw new FileNotFoundException("Path not found: " + path);
} }
@ -2372,7 +2372,7 @@ ContentSummary getContentSummary(String src)
String srcs = normalizePath(src); String srcs = normalizePath(src);
readLock(); readLock();
try { try {
INode targetNode = rootDir.getNode(srcs, false); INode targetNode = getNode(srcs, false);
if (targetNode == null) { if (targetNode == null) {
throw new FileNotFoundException("File does not exist: " + srcs); throw new FileNotFoundException("File does not exist: " + srcs);
} }
@ -2470,7 +2470,7 @@ INodeDirectory unprotectedSetQuota(String src, long nsQuota, long dsQuota)
} }
String srcs = normalizePath(src); String srcs = normalizePath(src);
final INodesInPath iip = rootDir.getINodesInPath4Write(srcs, true); final INodesInPath iip = 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.");
@ -2753,7 +2753,7 @@ void modifyAclEntries(String src, List<AclEntry> aclSpec) throws IOException {
private List<AclEntry> unprotectedModifyAclEntries(String src, private List<AclEntry> unprotectedModifyAclEntries(String src,
List<AclEntry> aclSpec) throws IOException { List<AclEntry> aclSpec) throws IOException {
assert hasWriteLock(); assert hasWriteLock();
INodesInPath iip = rootDir.getINodesInPath4Write(normalizePath(src), true); INodesInPath iip = getINodesInPath4Write(normalizePath(src), true);
INode inode = resolveLastINode(src, iip); INode inode = resolveLastINode(src, iip);
int snapshotId = iip.getLatestSnapshotId(); int snapshotId = iip.getLatestSnapshotId();
List<AclEntry> existingAcl = AclStorage.readINodeLogicalAcl(inode); List<AclEntry> existingAcl = AclStorage.readINodeLogicalAcl(inode);
@ -2776,7 +2776,7 @@ void removeAclEntries(String src, List<AclEntry> aclSpec) throws IOException {
private List<AclEntry> unprotectedRemoveAclEntries(String src, private List<AclEntry> unprotectedRemoveAclEntries(String src,
List<AclEntry> aclSpec) throws IOException { List<AclEntry> aclSpec) throws IOException {
assert hasWriteLock(); assert hasWriteLock();
INodesInPath iip = rootDir.getINodesInPath4Write(normalizePath(src), true); INodesInPath iip = getINodesInPath4Write(normalizePath(src), true);
INode inode = resolveLastINode(src, iip); INode inode = resolveLastINode(src, iip);
int snapshotId = iip.getLatestSnapshotId(); int snapshotId = iip.getLatestSnapshotId();
List<AclEntry> existingAcl = AclStorage.readINodeLogicalAcl(inode); List<AclEntry> existingAcl = AclStorage.readINodeLogicalAcl(inode);
@ -2799,7 +2799,7 @@ void removeDefaultAcl(String src) throws IOException {
private List<AclEntry> unprotectedRemoveDefaultAcl(String src) private List<AclEntry> unprotectedRemoveDefaultAcl(String src)
throws IOException { throws IOException {
assert hasWriteLock(); assert hasWriteLock();
INodesInPath iip = rootDir.getINodesInPath4Write(normalizePath(src), true); INodesInPath iip = getINodesInPath4Write(normalizePath(src), true);
INode inode = resolveLastINode(src, iip); INode inode = resolveLastINode(src, iip);
int snapshotId = iip.getLatestSnapshotId(); int snapshotId = iip.getLatestSnapshotId();
List<AclEntry> existingAcl = AclStorage.readINodeLogicalAcl(inode); List<AclEntry> existingAcl = AclStorage.readINodeLogicalAcl(inode);
@ -2821,7 +2821,7 @@ void removeAcl(String src) throws IOException {
private void unprotectedRemoveAcl(String src) throws IOException { private void unprotectedRemoveAcl(String src) throws IOException {
assert hasWriteLock(); assert hasWriteLock();
INodesInPath iip = rootDir.getINodesInPath4Write(normalizePath(src), true); INodesInPath iip = getINodesInPath4Write(normalizePath(src), true);
INode inode = resolveLastINode(src, iip); INode inode = resolveLastINode(src, iip);
int snapshotId = iip.getLatestSnapshotId(); int snapshotId = iip.getLatestSnapshotId();
AclStorage.removeINodeAcl(inode, snapshotId); AclStorage.removeINodeAcl(inode, snapshotId);
@ -2846,7 +2846,7 @@ List<AclEntry> unprotectedSetAcl(String src, List<AclEntry> aclSpec)
} }
assert hasWriteLock(); assert hasWriteLock();
INodesInPath iip = rootDir.getINodesInPath4Write(normalizePath(src), true); INodesInPath iip = getINodesInPath4Write(normalizePath(src), true);
INode inode = resolveLastINode(src, iip); INode inode = resolveLastINode(src, iip);
int snapshotId = iip.getLatestSnapshotId(); int snapshotId = iip.getLatestSnapshotId();
List<AclEntry> existingAcl = AclStorage.readINodeLogicalAcl(inode); List<AclEntry> existingAcl = AclStorage.readINodeLogicalAcl(inode);
@ -2866,7 +2866,7 @@ AclStatus getAclStatus(String src) throws IOException {
getINode4DotSnapshot(srcs) != null) { getINode4DotSnapshot(srcs) != null) {
return new AclStatus.Builder().owner("").group("").build(); return new AclStatus.Builder().owner("").group("").build();
} }
INodesInPath iip = rootDir.getLastINodeInPath(srcs, true); INodesInPath iip = getLastINodeInPath(srcs, true);
INode inode = resolveLastINode(src, iip); INode inode = resolveLastINode(src, iip);
int snapshotId = iip.getPathSnapshotId(); int snapshotId = iip.getPathSnapshotId();
List<AclEntry> acl = AclStorage.readINodeAcl(inode, snapshotId); List<AclEntry> acl = AclStorage.readINodeAcl(inode, snapshotId);
@ -2978,7 +2978,18 @@ public static byte[][] getPathComponentsWithSnapshot(INode inode) {
static byte[][] getPathComponentsForReservedPath(String src) { static byte[][] getPathComponentsForReservedPath(String src) {
return !isReservedName(src) ? null : INode.getPathComponents(src); return !isReservedName(src) ? null : INode.getPathComponents(src);
} }
/** Check if a given inode name is reserved */
public static boolean isReservedName(INode inode) {
return CHECK_RESERVED_FILE_NAMES
&& Arrays.equals(inode.getLocalNameBytes(), DOT_RESERVED);
}
/** Check if a given path is reserved */
public static boolean isReservedName(String src) {
return src.startsWith(DOT_RESERVED_PATH_PREFIX);
}
/** /**
* Resolve the path of /.reserved/.inodes/<inodeid>/... to a regular path * Resolve the path of /.reserved/.inodes/<inodeid>/... to a regular path
* *
@ -3038,15 +3049,53 @@ static String resolvePath(String src, byte[][] pathComponents, FSDirectory fsd)
} }
return path.toString(); return path.toString();
} }
/** Check if a given inode name is reserved */ /** @return the {@link INodesInPath} containing only the last inode. */
public static boolean isReservedName(INode inode) { private INodesInPath getLastINodeInPath(String path, boolean resolveLink
return CHECK_RESERVED_FILE_NAMES ) throws UnresolvedLinkException {
&& Arrays.equals(inode.getLocalNameBytes(), DOT_RESERVED); return INodesInPath.resolve(rootDir, INode.getPathComponents(path), 1,
resolveLink);
} }
/** Check if a given path is reserved */ /** @return the {@link INodesInPath} containing all inodes in the path. */
public static boolean isReservedName(String src) { INodesInPath getINodesInPath(String path, boolean resolveLink
return src.startsWith(DOT_RESERVED_PATH_PREFIX); ) throws UnresolvedLinkException {
final byte[][] components = INode.getPathComponents(path);
return INodesInPath.resolve(rootDir, components, components.length,
resolveLink);
}
/** @return the last inode in the path. */
INode getNode(String path, boolean resolveLink)
throws UnresolvedLinkException {
return getLastINodeInPath(path, resolveLink).getINode(0);
}
/**
* @return the INode of the last component in src, or null if the last
* component does not exist.
* @throws UnresolvedLinkException if symlink can't be resolved
* @throws SnapshotAccessControlException if path is in RO snapshot
*/
private INode getINode4Write(String src, boolean resolveLink)
throws UnresolvedLinkException, SnapshotAccessControlException {
return getINodesInPath4Write(src, resolveLink).getLastINode();
}
/**
* @return the INodesInPath of the components in src
* @throws UnresolvedLinkException if symlink can't be resolved
* @throws SnapshotAccessControlException if path is in RO snapshot
*/
private INodesInPath getINodesInPath4Write(String src, boolean resolveLink)
throws UnresolvedLinkException, SnapshotAccessControlException {
final byte[][] components = INode.getPathComponents(src);
INodesInPath inodesInPath = INodesInPath.resolve(rootDir, components,
components.length, resolveLink);
if (inodesInPath.isSnapshot()) {
throw new SnapshotAccessControlException(
"Modification on a read-only snapshot is disallowed");
}
return inodesInPath;
} }
} }

View File

@ -495,7 +495,7 @@ private int loadDirectory(DataInput in, Counter counter) throws IOException {
// Rename .snapshot paths if we're doing an upgrade // Rename .snapshot paths if we're doing an upgrade
parentPath = renameReservedPathsOnUpgrade(parentPath, getLayoutVersion()); parentPath = renameReservedPathsOnUpgrade(parentPath, getLayoutVersion());
final INodeDirectory parent = INodeDirectory.valueOf( final INodeDirectory parent = INodeDirectory.valueOf(
namesystem.dir.rootDir.getNode(parentPath, true), parentPath); namesystem.dir.getNode(parentPath, true), parentPath);
return loadChildren(parent, in, counter); return loadChildren(parent, in, counter);
} }

View File

@ -5506,7 +5506,7 @@ private void checkPermission(FSPermissionChecker pc,
dir.waitForReady(); dir.waitForReady();
readLock(); readLock();
try { try {
pc.checkPermission(path, dir.rootDir, doCheckOwner, ancestorAccess, pc.checkPermission(path, dir, doCheckOwner, ancestorAccess,
parentAccess, access, subAccess, resolveLink); parentAccess, access, subAccess, resolveLink);
} finally { } finally {
readUnlock(); readUnlock();

View File

@ -144,7 +144,7 @@ public void checkSuperuserPrivilege()
* Guarded by {@link FSNamesystem#readLock()} * Guarded by {@link FSNamesystem#readLock()}
* Caller of this method must hold that lock. * Caller of this method must hold that lock.
*/ */
void checkPermission(String path, INodeDirectory root, boolean doCheckOwner, void checkPermission(String path, FSDirectory dir, boolean doCheckOwner,
FsAction ancestorAccess, FsAction parentAccess, FsAction access, FsAction ancestorAccess, FsAction parentAccess, FsAction access,
FsAction subAccess, boolean resolveLink) FsAction subAccess, boolean resolveLink)
throws AccessControlException, UnresolvedLinkException { throws AccessControlException, UnresolvedLinkException {
@ -159,7 +159,7 @@ void checkPermission(String path, INodeDirectory root, boolean doCheckOwner,
} }
// check if (parentAccess != null) && file exists, then check sb // check if (parentAccess != null) && file exists, then check sb
// If resolveLink, the check is performed on the link target. // If resolveLink, the check is performed on the link target.
final INodesInPath inodesInPath = root.getINodesInPath(path, resolveLink); final INodesInPath inodesInPath = dir.getINodesInPath(path, resolveLink);
final int snapshotId = inodesInPath.getPathSnapshotId(); final int snapshotId = inodesInPath.getPathSnapshotId();
final INode[] inodes = inodesInPath.getINodes(); final INode[] inodes = inodesInPath.getINodes();
int ancestorIndex = inodes.length - 2; int ancestorIndex = inodes.length - 2;

View File

@ -403,53 +403,6 @@ private ReadOnlyList<INode> getCurrentChildrenList() {
: ReadOnlyList.Util.asReadOnlyList(children); : ReadOnlyList.Util.asReadOnlyList(children);
} }
/** @return the {@link INodesInPath} containing only the last inode. */
INodesInPath getLastINodeInPath(String path, boolean resolveLink
) throws UnresolvedLinkException {
return INodesInPath.resolve(this, 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 INodesInPath.resolve(this, components, components.length, resolveLink);
}
/** @return the last inode in the path. */
INode getNode(String path, boolean resolveLink)
throws UnresolvedLinkException {
return getLastINodeInPath(path, resolveLink).getINode(0);
}
/**
* @return the INode of the last component in src, or null if the last
* component does not exist.
* @throws UnresolvedLinkException if symlink can't be resolved
* @throws SnapshotAccessControlException if path is in RO snapshot
*/
INode getINode4Write(String src, boolean resolveLink)
throws UnresolvedLinkException, SnapshotAccessControlException {
return getINodesInPath4Write(src, resolveLink).getLastINode();
}
/**
* @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 getINodesInPath4Write(String src, boolean resolveLink)
throws UnresolvedLinkException, SnapshotAccessControlException {
final byte[][] components = INode.getPathComponents(src);
INodesInPath inodesInPath = INodesInPath.resolve(this, components,
components.length, resolveLink);
if (inodesInPath.isSnapshot()) {
throw new SnapshotAccessControlException(
"Modification on a read-only snapshot is disallowed");
}
return inodesInPath;
}
/** /**
* Given a child's name, return the index of the next child * Given a child's name, return the index of the next child
* *

View File

@ -1306,7 +1306,7 @@ private static void assertAclFeature(boolean expectAclFeature)
*/ */
private static void assertAclFeature(Path pathToCheck, private static void assertAclFeature(Path pathToCheck,
boolean expectAclFeature) throws IOException { boolean expectAclFeature) throws IOException {
INode inode = cluster.getNamesystem().getFSDirectory().getRoot() INode inode = cluster.getNamesystem().getFSDirectory()
.getNode(pathToCheck.toUri().getPath(), false); .getNode(pathToCheck.toUri().getPath(), false);
assertNotNull(inode); assertNotNull(inode);
AclFeature aclFeature = inode.getAclFeature(); AclFeature aclFeature = inode.getAclFeature();

View File

@ -26,6 +26,7 @@
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import org.apache.hadoop.conf.Configuration;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -38,7 +39,10 @@
import org.apache.hadoop.hdfs.server.namenode.snapshot.Snapshot; import org.apache.hadoop.hdfs.server.namenode.snapshot.Snapshot;
import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import static org.mockito.Mockito.*;
/** /**
* Unit tests covering FSPermissionChecker. All tests in this suite have been * Unit tests covering FSPermissionChecker. All tests in this suite have been
* cross-validated against Linux setfacl/getfacl to check for consistency of the * cross-validated against Linux setfacl/getfacl to check for consistency of the
@ -56,14 +60,24 @@ public class TestFSPermissionChecker {
private static final UserGroupInformation CLARK = private static final UserGroupInformation CLARK =
UserGroupInformation.createUserForTesting("clark", new String[] { "execs" }); UserGroupInformation.createUserForTesting("clark", new String[] { "execs" });
private FSDirectory dir;
private INodeDirectory inodeRoot; private INodeDirectory inodeRoot;
@Before @Before
public void setUp() { public void setUp() {
PermissionStatus permStatus = PermissionStatus.createImmutable(SUPERUSER, Configuration conf = new Configuration();
SUPERGROUP, FsPermission.createImmutable((short)0755)); FSNamesystem fsn = mock(FSNamesystem.class);
inodeRoot = new INodeDirectory(INodeId.ROOT_INODE_ID, doAnswer(new Answer() {
INodeDirectory.ROOT_NAME, permStatus, 0L); @Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
FsPermission perm = (FsPermission) args[0];
return new PermissionStatus(SUPERUSER, SUPERGROUP, perm);
}
}).when(fsn).createFsOwnerPermissions(any(FsPermission.class));
FSImage image = mock(FSImage.class);
dir = new FSDirectory(image, fsn, conf);
inodeRoot = dir.getRoot();
} }
@Test @Test
@ -379,14 +393,14 @@ private void addAcl(INodeWithAdditionalFields inode, AclEntry... acl)
private void assertPermissionGranted(UserGroupInformation user, String path, private void assertPermissionGranted(UserGroupInformation user, String path,
FsAction access) throws IOException { FsAction access) throws IOException {
new FSPermissionChecker(SUPERUSER, SUPERGROUP, user).checkPermission(path, new FSPermissionChecker(SUPERUSER, SUPERGROUP, user).checkPermission(path,
inodeRoot, false, null, null, access, null, true); dir, false, null, null, access, null, true);
} }
private void assertPermissionDenied(UserGroupInformation user, String path, private void assertPermissionDenied(UserGroupInformation user, String path,
FsAction access) throws IOException { FsAction access) throws IOException {
try { try {
new FSPermissionChecker(SUPERUSER, SUPERGROUP, user).checkPermission(path, new FSPermissionChecker(SUPERUSER, SUPERGROUP, user).checkPermission(path,
inodeRoot, false, null, null, access, null, true); dir, false, null, null, access, null, true);
fail("expected AccessControlException for user + " + user + ", path = " + fail("expected AccessControlException for user + " + user + ", path = " +
path + ", access = " + access); path + ", access = " + access);
} catch (AccessControlException e) { } catch (AccessControlException e) {

View File

@ -699,7 +699,7 @@ public void testFsckError() throws Exception {
DFSTestUtil.waitReplication(fs, filePath, (short)1); DFSTestUtil.waitReplication(fs, filePath, (short)1);
// intentionally corrupt NN data structure // intentionally corrupt NN data structure
INodeFile node = (INodeFile)cluster.getNamesystem().dir.rootDir.getNode( INodeFile node = (INodeFile)cluster.getNamesystem().dir.getNode(
fileName, true); fileName, true);
final BlockInfo[] blocks = node.getBlocks(); final BlockInfo[] blocks = node.getBlocks();
assertEquals(blocks.length, 1); assertEquals(blocks.length, 1);