HDFS-7474. Avoid resolving path in FSPermissionChecker. Contributed by Jing Zhao.
Conflicts: hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
This commit is contained in:
parent
b72fb6c774
commit
988ef8a462
|
@ -176,6 +176,8 @@ Release 2.7.0 - UNRELEASED
|
||||||
HDFS-7478. Move org.apache.hadoop.hdfs.server.namenode.NNConf to
|
HDFS-7478. Move org.apache.hadoop.hdfs.server.namenode.NNConf to
|
||||||
FSNamesystem. (Li Lu via wheat9)
|
FSNamesystem. (Li Lu via wheat9)
|
||||||
|
|
||||||
|
HDFS-7474. Avoid resolving path in FSPermissionChecker. (jing9)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
HDFS-7454. Reduce memory footprint for AclEntries in NameNode.
|
HDFS-7454. Reduce memory footprint for AclEntries in NameNode.
|
||||||
|
|
|
@ -285,12 +285,12 @@ public class EncryptionZoneManager {
|
||||||
CryptoProtocolVersion version, String keyName)
|
CryptoProtocolVersion version, String keyName)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
assert dir.hasWriteLock();
|
assert dir.hasWriteLock();
|
||||||
if (dir.isNonEmptyDirectory(src)) {
|
final INodesInPath srcIIP = dir.getINodesInPath4Write(src, false);
|
||||||
|
if (dir.isNonEmptyDirectory(srcIIP)) {
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Attempt to create an encryption zone for a non-empty directory.");
|
"Attempt to create an encryption zone for a non-empty directory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
final INodesInPath srcIIP = dir.getINodesInPath4Write(src, false);
|
|
||||||
if (srcIIP != null &&
|
if (srcIIP != null &&
|
||||||
srcIIP.getLastINode() != null &&
|
srcIIP.getLastINode() != null &&
|
||||||
!srcIIP.getLastINode().isDirectory()) {
|
!srcIIP.getLastINode().isDirectory()) {
|
||||||
|
|
|
@ -53,15 +53,17 @@ class FSDirConcatOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final INodesInPath trgIip = fsd.getINodesInPath4Write(target);
|
||||||
// write permission for the target
|
// write permission for the target
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
FSPermissionChecker pc = fsd.getPermissionChecker();
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
fsd.checkPathAccess(pc, target, FsAction.WRITE);
|
fsd.checkPathAccess(pc, trgIip, FsAction.WRITE);
|
||||||
|
|
||||||
// and srcs
|
// and srcs
|
||||||
for(String aSrc: srcs) {
|
for(String aSrc: srcs) {
|
||||||
fsd.checkPathAccess(pc, aSrc, FsAction.READ); // read the file
|
final INodesInPath srcIip = fsd.getINodesInPath4Write(aSrc);
|
||||||
fsd.checkParentAccess(pc, aSrc, FsAction.WRITE); // for delete
|
fsd.checkPathAccess(pc, srcIip, FsAction.READ); // read the file
|
||||||
|
fsd.checkParentAccess(pc, srcIip, FsAction.WRITE); // for delete
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +74,6 @@ class FSDirConcatOp {
|
||||||
// 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 INodesInPath trgIip = fsd.getINodesInPath4Write(target);
|
|
||||||
if (fsd.getEZForPath(trgIip) != null) {
|
if (fsd.getEZForPath(trgIip) != null) {
|
||||||
throw new HadoopIllegalArgumentException(
|
throw new HadoopIllegalArgumentException(
|
||||||
"concat can not be called for files in an encryption zone.");
|
"concat can not be called for files in an encryption zone.");
|
||||||
|
|
|
@ -53,17 +53,18 @@ class FSDirMkdirOp {
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath
|
||||||
(src);
|
(src);
|
||||||
src = fsd.resolvePath(pc, src, pathComponents);
|
src = fsd.resolvePath(pc, src, pathComponents);
|
||||||
|
INodesInPath iip = fsd.getINodesInPath4Write(src);
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
fsd.checkTraverse(pc, src);
|
fsd.checkTraverse(pc, iip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isDirMutable(fsd, src)) {
|
if (!isDirMutable(fsd, iip)) {
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
fsd.checkAncestorAccess(pc, src, FsAction.WRITE);
|
fsd.checkAncestorAccess(pc, iip, FsAction.WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!createParent) {
|
if (!createParent) {
|
||||||
fsd.verifyParentDir(src);
|
fsd.verifyParentDir(iip, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate that we have enough inodes. This is, at best, a
|
// validate that we have enough inodes. This is, at best, a
|
||||||
|
@ -203,13 +204,11 @@ class FSDirMkdirOp {
|
||||||
* Check whether the path specifies a directory
|
* Check whether the path specifies a directory
|
||||||
* @throws SnapshotAccessControlException if path is in RO snapshot
|
* @throws SnapshotAccessControlException if path is in RO snapshot
|
||||||
*/
|
*/
|
||||||
private static boolean isDirMutable(
|
private static boolean isDirMutable(FSDirectory fsd, INodesInPath iip)
|
||||||
FSDirectory fsd, String src) throws UnresolvedLinkException,
|
throws SnapshotAccessControlException {
|
||||||
SnapshotAccessControlException {
|
|
||||||
src = FSDirectory.normalizePath(src);
|
|
||||||
fsd.readLock();
|
fsd.readLock();
|
||||||
try {
|
try {
|
||||||
INode node = fsd.getINode4Write(src, false);
|
INode node = iip.getLastINode();
|
||||||
return node != null && node.isDirectory();
|
return node != null && node.isDirectory();
|
||||||
} finally {
|
} finally {
|
||||||
fsd.readUnlock();
|
fsd.readUnlock();
|
||||||
|
|
|
@ -492,11 +492,13 @@ class FSDirRenameOp {
|
||||||
// Rename does not operates on link targets
|
// Rename does not operates on link targets
|
||||||
// Do not resolveLink when checking permissions of src and dst
|
// Do not resolveLink when checking permissions of src and dst
|
||||||
// Check write access to parent of src
|
// Check write access to parent of src
|
||||||
fsd.checkPermission(pc, src, false, null, FsAction.WRITE, null, null,
|
INodesInPath srcIIP = fsd.getINodesInPath(src, false);
|
||||||
false, false);
|
fsd.checkPermission(pc, srcIIP, false, null, FsAction.WRITE, null, null,
|
||||||
|
false);
|
||||||
|
INodesInPath dstIIP = fsd.getINodesInPath(actualdst, false);
|
||||||
// Check write access to ancestor of dst
|
// Check write access to ancestor of dst
|
||||||
fsd.checkPermission(pc, actualdst, false, FsAction.WRITE, null, null,
|
fsd.checkPermission(pc, dstIIP, false, FsAction.WRITE, null, null,
|
||||||
null, false, false);
|
null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
long mtime = now();
|
long mtime = now();
|
||||||
|
@ -518,11 +520,13 @@ class FSDirRenameOp {
|
||||||
// Rename does not operates on link targets
|
// Rename does not operates on link targets
|
||||||
// Do not resolveLink when checking permissions of src and dst
|
// Do not resolveLink when checking permissions of src and dst
|
||||||
// Check write access to parent of src
|
// Check write access to parent of src
|
||||||
fsd.checkPermission(pc, src, false, null, FsAction.WRITE, null, null,
|
INodesInPath srcIIP = fsd.getINodesInPath(src, false);
|
||||||
false, false);
|
fsd.checkPermission(pc, srcIIP, false, null, FsAction.WRITE, null, null,
|
||||||
|
false);
|
||||||
// Check write access to ancestor of dst
|
// Check write access to ancestor of dst
|
||||||
fsd.checkPermission(pc, dst, false, FsAction.WRITE, null, null, null,
|
INodesInPath dstIIP = fsd.getINodesInPath(dst, false);
|
||||||
false, false);
|
fsd.checkPermission(pc, dstIIP, false, FsAction.WRITE, null, null, null,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
long mtime = now();
|
long mtime = now();
|
||||||
|
|
|
@ -81,27 +81,24 @@ class FSDirSnapshotOp {
|
||||||
FSDirectory fsd, SnapshotManager snapshotManager, String snapshotRoot,
|
FSDirectory fsd, SnapshotManager snapshotManager, String snapshotRoot,
|
||||||
String snapshotName, boolean logRetryCache)
|
String snapshotName, boolean logRetryCache)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final FSPermissionChecker pc = fsd.getPermissionChecker();
|
final INodesInPath iip = fsd.getINodesInPath4Write(snapshotRoot);
|
||||||
|
|
||||||
String snapshotPath = null;
|
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
fsd.checkOwner(pc, snapshotRoot);
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
|
fsd.checkOwner(pc, iip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snapshotName == null || snapshotName.isEmpty()) {
|
if (snapshotName == null || snapshotName.isEmpty()) {
|
||||||
snapshotName = Snapshot.generateDefaultSnapshotName();
|
snapshotName = Snapshot.generateDefaultSnapshotName();
|
||||||
|
} else if (!DFSUtil.isValidNameForComponent(snapshotName)) {
|
||||||
|
throw new InvalidPathException("Invalid snapshot name: " + snapshotName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(snapshotName != null){
|
String snapshotPath = null;
|
||||||
if (!DFSUtil.isValidNameForComponent(snapshotName)) {
|
|
||||||
throw new InvalidPathException("Invalid snapshot name: " +
|
|
||||||
snapshotName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
verifySnapshotName(fsd, snapshotName, snapshotRoot);
|
verifySnapshotName(fsd, snapshotName, snapshotRoot);
|
||||||
fsd.writeLock();
|
fsd.writeLock();
|
||||||
try {
|
try {
|
||||||
snapshotPath = snapshotManager.createSnapshot(snapshotRoot, snapshotName);
|
snapshotPath = snapshotManager.createSnapshot(iip, snapshotRoot,
|
||||||
|
snapshotName);
|
||||||
} finally {
|
} finally {
|
||||||
fsd.writeUnlock();
|
fsd.writeUnlock();
|
||||||
}
|
}
|
||||||
|
@ -114,15 +111,16 @@ class FSDirSnapshotOp {
|
||||||
static void renameSnapshot(FSDirectory fsd, SnapshotManager snapshotManager,
|
static void renameSnapshot(FSDirectory fsd, SnapshotManager snapshotManager,
|
||||||
String path, String snapshotOldName, String snapshotNewName,
|
String path, String snapshotOldName, String snapshotNewName,
|
||||||
boolean logRetryCache) throws IOException {
|
boolean logRetryCache) throws IOException {
|
||||||
|
final INodesInPath iip = fsd.getINodesInPath4Write(path);
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
FSPermissionChecker pc = fsd.getPermissionChecker();
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
fsd.checkOwner(pc, path);
|
fsd.checkOwner(pc, iip);
|
||||||
}
|
}
|
||||||
verifySnapshotName(fsd, snapshotNewName, path);
|
verifySnapshotName(fsd, snapshotNewName, path);
|
||||||
fsd.writeLock();
|
fsd.writeLock();
|
||||||
try {
|
try {
|
||||||
snapshotManager.renameSnapshot(path, snapshotOldName, snapshotNewName);
|
snapshotManager.renameSnapshot(iip, path, snapshotOldName,
|
||||||
|
snapshotNewName);
|
||||||
} finally {
|
} finally {
|
||||||
fsd.writeUnlock();
|
fsd.writeUnlock();
|
||||||
}
|
}
|
||||||
|
@ -142,8 +140,8 @@ class FSDirSnapshotOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SnapshotDiffReport getSnapshotDiffReport(
|
static SnapshotDiffReport getSnapshotDiffReport(FSDirectory fsd,
|
||||||
FSDirectory fsd, SnapshotManager snapshotManager, String path,
|
SnapshotManager snapshotManager, String path,
|
||||||
String fromSnapshot, String toSnapshot) throws IOException {
|
String fromSnapshot, String toSnapshot) throws IOException {
|
||||||
SnapshotDiffReport diffs;
|
SnapshotDiffReport diffs;
|
||||||
final FSPermissionChecker pc = fsd.getPermissionChecker();
|
final FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
|
@ -153,7 +151,8 @@ class FSDirSnapshotOp {
|
||||||
checkSubtreeReadPermission(fsd, pc, path, fromSnapshot);
|
checkSubtreeReadPermission(fsd, pc, path, fromSnapshot);
|
||||||
checkSubtreeReadPermission(fsd, pc, path, toSnapshot);
|
checkSubtreeReadPermission(fsd, pc, path, toSnapshot);
|
||||||
}
|
}
|
||||||
diffs = snapshotManager.diff(path, fromSnapshot, toSnapshot);
|
INodesInPath iip = fsd.getINodesInPath(path, true);
|
||||||
|
diffs = snapshotManager.diff(iip, path, fromSnapshot, toSnapshot);
|
||||||
} finally {
|
} finally {
|
||||||
fsd.readUnlock();
|
fsd.readUnlock();
|
||||||
}
|
}
|
||||||
|
@ -170,18 +169,18 @@ class FSDirSnapshotOp {
|
||||||
FSDirectory fsd, SnapshotManager snapshotManager, String snapshotRoot,
|
FSDirectory fsd, SnapshotManager snapshotManager, String snapshotRoot,
|
||||||
String snapshotName, boolean logRetryCache)
|
String snapshotName, boolean logRetryCache)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final FSPermissionChecker pc = fsd.getPermissionChecker();
|
final INodesInPath iip = fsd.getINodesInPath4Write(snapshotRoot);
|
||||||
|
|
||||||
INode.BlocksMapUpdateInfo collectedBlocks = new INode.BlocksMapUpdateInfo();
|
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
fsd.checkOwner(pc, snapshotRoot);
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
|
fsd.checkOwner(pc, iip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INode.BlocksMapUpdateInfo collectedBlocks = new INode.BlocksMapUpdateInfo();
|
||||||
ChunkedArrayList<INode> removedINodes = new ChunkedArrayList<INode>();
|
ChunkedArrayList<INode> removedINodes = new ChunkedArrayList<INode>();
|
||||||
fsd.writeLock();
|
fsd.writeLock();
|
||||||
try {
|
try {
|
||||||
snapshotManager.deleteSnapshot(snapshotRoot, snapshotName,
|
snapshotManager.deleteSnapshot(iip, snapshotName, collectedBlocks,
|
||||||
collectedBlocks, removedINodes);
|
removedINodes);
|
||||||
fsd.removeFromInodeMap(removedINodes);
|
fsd.removeFromInodeMap(removedINodes);
|
||||||
} finally {
|
} finally {
|
||||||
fsd.writeUnlock();
|
fsd.writeUnlock();
|
||||||
|
@ -199,7 +198,8 @@ class FSDirSnapshotOp {
|
||||||
final String fromPath = snapshot == null ?
|
final String fromPath = snapshot == null ?
|
||||||
snapshottablePath : Snapshot.getSnapshotPath(snapshottablePath,
|
snapshottablePath : Snapshot.getSnapshotPath(snapshottablePath,
|
||||||
snapshot);
|
snapshot);
|
||||||
fsd.checkPermission(pc, fromPath, false, null, null, FsAction.READ,
|
INodesInPath iip = fsd.getINodesInPath(fromPath, true);
|
||||||
|
fsd.checkPermission(pc, iip, false, null, null, FsAction.READ,
|
||||||
FsAction.READ);
|
FsAction.READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,15 +45,14 @@ import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
class FSDirStatAndListingOp {
|
class FSDirStatAndListingOp {
|
||||||
static DirectoryListing getListingInt(
|
static DirectoryListing getListingInt(FSDirectory fsd, final String srcArg,
|
||||||
FSDirectory fsd, final String srcArg, byte[] startAfter,
|
byte[] startAfter, boolean needLocation) throws IOException {
|
||||||
boolean needLocation)
|
|
||||||
throws IOException {
|
|
||||||
String src = srcArg;
|
|
||||||
FSPermissionChecker pc = fsd.getPermissionChecker();
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
byte[][] pathComponents = FSDirectory
|
||||||
String startAfterString = new String(startAfter);
|
.getPathComponentsForReservedPath(srcArg);
|
||||||
src = fsd.resolvePath(pc, src, pathComponents);
|
final String startAfterString = new String(startAfter);
|
||||||
|
final String src = fsd.resolvePath(pc, srcArg, pathComponents);
|
||||||
|
final INodesInPath iip = fsd.getINodesInPath(src, true);
|
||||||
|
|
||||||
// Get file name when startAfter is an INodePath
|
// Get file name when startAfter is an INodePath
|
||||||
if (FSDirectory.isReservedName(startAfterString)) {
|
if (FSDirectory.isReservedName(startAfterString)) {
|
||||||
|
@ -73,9 +72,9 @@ class FSDirStatAndListingOp {
|
||||||
boolean isSuperUser = true;
|
boolean isSuperUser = true;
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
if (fsd.isDir(src)) {
|
if (fsd.isDir(src)) {
|
||||||
fsd.checkPathAccess(pc, src, FsAction.READ_EXECUTE);
|
fsd.checkPathAccess(pc, iip, FsAction.READ_EXECUTE);
|
||||||
} else {
|
} else {
|
||||||
fsd.checkTraverse(pc, src);
|
fsd.checkTraverse(pc, iip);
|
||||||
}
|
}
|
||||||
isSuperUser = pc.isSuperUser();
|
isSuperUser = pc.isSuperUser();
|
||||||
}
|
}
|
||||||
|
@ -102,10 +101,10 @@ class FSDirStatAndListingOp {
|
||||||
FSPermissionChecker pc = fsd.getPermissionChecker();
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
||||||
src = fsd.resolvePath(pc, src, pathComponents);
|
src = fsd.resolvePath(pc, src, pathComponents);
|
||||||
|
final INodesInPath iip = fsd.getINodesInPath(src, resolveLink);
|
||||||
boolean isSuperUser = true;
|
boolean isSuperUser = true;
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
fsd.checkPermission(pc, src, false, null, null, null, null, false,
|
fsd.checkPermission(pc, iip, false, null, null, null, null, false);
|
||||||
resolveLink);
|
|
||||||
isSuperUser = pc.isSuperUser();
|
isSuperUser = pc.isSuperUser();
|
||||||
}
|
}
|
||||||
return getFileInfo(fsd, src, resolveLink,
|
return getFileInfo(fsd, src, resolveLink,
|
||||||
|
@ -119,10 +118,13 @@ class FSDirStatAndListingOp {
|
||||||
FSPermissionChecker pc = fsd.getPermissionChecker();
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
||||||
src = fsd.resolvePath(pc, src, pathComponents);
|
src = fsd.resolvePath(pc, src, pathComponents);
|
||||||
|
final INodesInPath iip = fsd.getINodesInPath(src, true);
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
fsd.checkTraverse(pc, src);
|
fsd.checkTraverse(pc, iip);
|
||||||
}
|
}
|
||||||
return !INodeFile.valueOf(fsd.getINode(src), src).isUnderConstruction();
|
INode[] inodes = iip.getINodes();
|
||||||
|
return !INodeFile.valueOf(inodes[inodes.length - 1],
|
||||||
|
src).isUnderConstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ContentSummary getContentSummary(
|
static ContentSummary getContentSummary(
|
||||||
|
@ -130,8 +132,9 @@ class FSDirStatAndListingOp {
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
||||||
FSPermissionChecker pc = fsd.getPermissionChecker();
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
||||||
src = fsd.resolvePath(pc, src, pathComponents);
|
src = fsd.resolvePath(pc, src, pathComponents);
|
||||||
|
final INodesInPath iip = fsd.getINodesInPath(src, true);
|
||||||
if (fsd.isPermissionEnabled()) {
|
if (fsd.isPermissionEnabled()) {
|
||||||
fsd.checkPermission(pc, src, false, null, null, null,
|
fsd.checkPermission(pc, iip, false, null, null, null,
|
||||||
FsAction.READ_EXECUTE);
|
FsAction.READ_EXECUTE);
|
||||||
}
|
}
|
||||||
return getContentSummaryInt(fsd, src);
|
return getContentSummaryInt(fsd, src);
|
||||||
|
@ -249,7 +252,7 @@ class FSDirStatAndListingOp {
|
||||||
Snapshot.Root sRoot = snapshots.get(i + skipSize).getRoot();
|
Snapshot.Root sRoot = snapshots.get(i + skipSize).getRoot();
|
||||||
listing[i] = createFileStatus(fsd, sRoot.getLocalNameBytes(), sRoot,
|
listing[i] = createFileStatus(fsd, sRoot.getLocalNameBytes(), sRoot,
|
||||||
BlockStoragePolicySuite.ID_UNSPECIFIED, Snapshot.CURRENT_STATE_ID,
|
BlockStoragePolicySuite.ID_UNSPECIFIED, Snapshot.CURRENT_STATE_ID,
|
||||||
false, null);
|
false, INodesInPath.fromINode(sRoot));
|
||||||
}
|
}
|
||||||
return new DirectoryListing(
|
return new DirectoryListing(
|
||||||
listing, snapshots.size() - skipSize - numOfListing);
|
listing, snapshots.size() - skipSize - numOfListing);
|
||||||
|
|
|
@ -476,7 +476,7 @@ public class FSDirectory implements Closeable {
|
||||||
/**
|
/**
|
||||||
* This is a wrapper for resolvePath(). If the path passed
|
* This is a wrapper for resolvePath(). If the path passed
|
||||||
* is prefixed with /.reserved/raw, then it checks to ensure that the caller
|
* is prefixed with /.reserved/raw, then it checks to ensure that the caller
|
||||||
* has super user has super user privileges.
|
* has super user privileges.
|
||||||
*
|
*
|
||||||
* @param pc The permission checker used when resolving path.
|
* @param pc The permission checker used when resolving path.
|
||||||
* @param path The path to resolve.
|
* @param path The path to resolve.
|
||||||
|
@ -555,23 +555,23 @@ public class FSDirectory implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set block storage policy for a directory */
|
/** Set block storage policy for a directory */
|
||||||
void setStoragePolicy(String src, byte policyId)
|
void setStoragePolicy(INodesInPath iip, byte policyId)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
writeLock();
|
writeLock();
|
||||||
try {
|
try {
|
||||||
unprotectedSetStoragePolicy(src, policyId);
|
unprotectedSetStoragePolicy(iip, policyId);
|
||||||
} finally {
|
} finally {
|
||||||
writeUnlock();
|
writeUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unprotectedSetStoragePolicy(String src, byte policyId)
|
void unprotectedSetStoragePolicy(INodesInPath iip, byte policyId)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
final INodesInPath iip = getINodesInPath4Write(src, true);
|
|
||||||
final INode inode = iip.getLastINode();
|
final INode inode = iip.getLastINode();
|
||||||
if (inode == null) {
|
if (inode == null) {
|
||||||
throw new FileNotFoundException("File/Directory does not exist: " + src);
|
throw new FileNotFoundException("File/Directory does not exist: "
|
||||||
|
+ iip.getPath());
|
||||||
}
|
}
|
||||||
final int snapshotId = iip.getLatestSnapshotId();
|
final int snapshotId = iip.getLatestSnapshotId();
|
||||||
if (inode.isFile()) {
|
if (inode.isFile()) {
|
||||||
|
@ -593,7 +593,8 @@ public class FSDirectory implements Closeable {
|
||||||
} else if (inode.isDirectory()) {
|
} else if (inode.isDirectory()) {
|
||||||
setDirStoragePolicy(inode.asDirectory(), policyId, snapshotId);
|
setDirStoragePolicy(inode.asDirectory(), policyId, snapshotId);
|
||||||
} else {
|
} else {
|
||||||
throw new FileNotFoundException(src + " is not a file or directory");
|
throw new FileNotFoundException(iip.getPath()
|
||||||
|
+ " is not a file or directory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,11 +729,11 @@ public class FSDirectory implements Closeable {
|
||||||
/**
|
/**
|
||||||
* @return true if the path is a non-empty directory; otherwise, return false.
|
* @return true if the path is a non-empty directory; otherwise, return false.
|
||||||
*/
|
*/
|
||||||
boolean isNonEmptyDirectory(String path) throws UnresolvedLinkException {
|
boolean isNonEmptyDirectory(INodesInPath inodesInPath) {
|
||||||
readLock();
|
readLock();
|
||||||
try {
|
try {
|
||||||
final INodesInPath inodesInPath = getLastINodeInPath(path, false);
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
final INode inode = inodesInPath.getINode(0);
|
final INode inode = inodes[inodes.length - 1];
|
||||||
if (inode == null || !inode.isDirectory()) {
|
if (inode == null || !inode.isDirectory()) {
|
||||||
//not found or not a directory
|
//not found or not a directory
|
||||||
return false;
|
return false;
|
||||||
|
@ -825,7 +826,7 @@ public class FSDirectory implements Closeable {
|
||||||
}
|
}
|
||||||
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
||||||
NameNode.stateChangeLog.debug("DIR* FSDirectory.unprotectedDelete: "
|
NameNode.stateChangeLog.debug("DIR* FSDirectory.unprotectedDelete: "
|
||||||
+ targetNode.getFullPathName() + " is removed");
|
+ iip.getPath() + " is removed");
|
||||||
}
|
}
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
@ -1858,9 +1859,6 @@ public class FSDirectory implements Closeable {
|
||||||
}
|
}
|
||||||
readLock();
|
readLock();
|
||||||
try {
|
try {
|
||||||
if (iip == null) {
|
|
||||||
iip = getINodesInPath(inode.getFullPathName(), true);
|
|
||||||
}
|
|
||||||
EncryptionZone encryptionZone = getEZForPath(iip);
|
EncryptionZone encryptionZone = getEZForPath(iip);
|
||||||
if (encryptionZone == null) {
|
if (encryptionZone == null) {
|
||||||
// not an encrypted file
|
// not an encrypted file
|
||||||
|
@ -1882,8 +1880,7 @@ public class FSDirectory implements Closeable {
|
||||||
|
|
||||||
if (fileXAttr == null) {
|
if (fileXAttr == null) {
|
||||||
NameNode.LOG.warn("Could not find encryption XAttr for file " +
|
NameNode.LOG.warn("Could not find encryption XAttr for file " +
|
||||||
inode.getFullPathName() + " in encryption zone " +
|
iip.getPath() + " in encryption zone " + encryptionZone.getPath());
|
||||||
encryptionZone.getPath());
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2307,31 +2304,28 @@ public class FSDirectory implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkOwner(FSPermissionChecker pc, String path)
|
void checkOwner(FSPermissionChecker pc, INodesInPath iip)
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
throws AccessControlException {
|
||||||
checkPermission(pc, path, true, null, null, null, null);
|
checkPermission(pc, iip, true, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkPathAccess(FSPermissionChecker pc, String path,
|
void checkPathAccess(FSPermissionChecker pc, INodesInPath iip,
|
||||||
FsAction access)
|
FsAction access) throws AccessControlException {
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
checkPermission(pc, iip, false, null, null, access, null);
|
||||||
checkPermission(pc, path, false, null, null, access, null);
|
|
||||||
}
|
}
|
||||||
void checkParentAccess(
|
void checkParentAccess(FSPermissionChecker pc, INodesInPath iip,
|
||||||
FSPermissionChecker pc, String path, FsAction access)
|
FsAction access) throws AccessControlException {
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
checkPermission(pc, iip, false, null, access, null, null);
|
||||||
checkPermission(pc, path, false, null, access, null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAncestorAccess(
|
void checkAncestorAccess(FSPermissionChecker pc, INodesInPath iip,
|
||||||
FSPermissionChecker pc, String path, FsAction access)
|
FsAction access) throws AccessControlException {
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
checkPermission(pc, iip, false, access, null, null, null);
|
||||||
checkPermission(pc, path, false, access, null, null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkTraverse(FSPermissionChecker pc, String path)
|
void checkTraverse(FSPermissionChecker pc, INodesInPath iip)
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
throws AccessControlException {
|
||||||
checkPermission(pc, path, false, null, null, null, null);
|
checkPermission(pc, iip, false, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2339,13 +2333,12 @@ public class FSDirectory implements Closeable {
|
||||||
* details of the parameters, see
|
* details of the parameters, see
|
||||||
* {@link FSPermissionChecker#checkPermission}.
|
* {@link FSPermissionChecker#checkPermission}.
|
||||||
*/
|
*/
|
||||||
void checkPermission(
|
void checkPermission(FSPermissionChecker pc, INodesInPath iip,
|
||||||
FSPermissionChecker pc, String path, boolean doCheckOwner,
|
boolean doCheckOwner, FsAction ancestorAccess, FsAction parentAccess,
|
||||||
FsAction ancestorAccess, FsAction parentAccess, FsAction access,
|
FsAction access, FsAction subAccess)
|
||||||
FsAction subAccess)
|
throws AccessControlException {
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
checkPermission(pc, iip, doCheckOwner, ancestorAccess,
|
||||||
checkPermission(pc, path, doCheckOwner, ancestorAccess,
|
parentAccess, access, subAccess, false);
|
||||||
parentAccess, access, subAccess, false, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2353,16 +2346,15 @@ public class FSDirectory implements Closeable {
|
||||||
* details of the parameters, see
|
* details of the parameters, see
|
||||||
* {@link FSPermissionChecker#checkPermission}.
|
* {@link FSPermissionChecker#checkPermission}.
|
||||||
*/
|
*/
|
||||||
void checkPermission(
|
void checkPermission(FSPermissionChecker pc, INodesInPath iip,
|
||||||
FSPermissionChecker pc, String path, boolean doCheckOwner,
|
boolean doCheckOwner, FsAction ancestorAccess, FsAction parentAccess,
|
||||||
FsAction ancestorAccess, FsAction parentAccess, FsAction access,
|
FsAction access, FsAction subAccess, boolean ignoreEmptyDir)
|
||||||
FsAction subAccess, boolean ignoreEmptyDir, boolean resolveLink)
|
throws AccessControlException {
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
|
||||||
if (!pc.isSuperUser()) {
|
if (!pc.isSuperUser()) {
|
||||||
readLock();
|
readLock();
|
||||||
try {
|
try {
|
||||||
pc.checkPermission(path, this, doCheckOwner, ancestorAccess,
|
pc.checkPermission(iip, doCheckOwner, ancestorAccess,
|
||||||
parentAccess, access, subAccess, ignoreEmptyDir, resolveLink);
|
parentAccess, access, subAccess, ignoreEmptyDir);
|
||||||
} finally {
|
} finally {
|
||||||
readUnlock();
|
readUnlock();
|
||||||
}
|
}
|
||||||
|
@ -2379,12 +2371,11 @@ public class FSDirectory implements Closeable {
|
||||||
/**
|
/**
|
||||||
* Verify that parent directory of src exists.
|
* Verify that parent directory of src exists.
|
||||||
*/
|
*/
|
||||||
void verifyParentDir(String src)
|
void verifyParentDir(INodesInPath iip, String src)
|
||||||
throws FileNotFoundException, ParentNotDirectoryException,
|
throws FileNotFoundException, ParentNotDirectoryException {
|
||||||
UnresolvedLinkException {
|
|
||||||
Path parent = new Path(src).getParent();
|
Path parent = new Path(src).getParent();
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
final INode parentNode = getINode(parent.toString());
|
final INode parentNode = iip.getINode(-2);
|
||||||
if (parentNode == null) {
|
if (parentNode == null) {
|
||||||
throw new FileNotFoundException("Parent directory doesn't exist: "
|
throw new FileNotFoundException("Parent directory doesn't exist: "
|
||||||
+ parent);
|
+ parent);
|
||||||
|
@ -2407,7 +2398,6 @@ public class FSDirectory implements Closeable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the last allocated inode id when fsimage or editlog is loaded.
|
* Set the last allocated inode id when fsimage or editlog is loaded.
|
||||||
* @param newValue
|
|
||||||
*/
|
*/
|
||||||
void resetLastInodeId(long newValue) throws IOException {
|
void resetLastInodeId(long newValue) throws IOException {
|
||||||
try {
|
try {
|
||||||
|
@ -2417,8 +2407,7 @@ public class FSDirectory implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Should only be used for tests to reset to any value
|
/** Should only be used for tests to reset to any value */
|
||||||
* @param newValue*/
|
|
||||||
void resetLastInodeIdWithoutChecking(long newValue) {
|
void resetLastInodeIdWithoutChecking(long newValue) {
|
||||||
inodeId.setCurrentValue(newValue);
|
inodeId.setCurrentValue(newValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -668,7 +668,8 @@ public class FSEditLogLoader {
|
||||||
final String snapshotRoot =
|
final String snapshotRoot =
|
||||||
renameReservedPathsOnUpgrade(createSnapshotOp.snapshotRoot,
|
renameReservedPathsOnUpgrade(createSnapshotOp.snapshotRoot,
|
||||||
logVersion);
|
logVersion);
|
||||||
String path = fsNamesys.getSnapshotManager().createSnapshot(
|
INodesInPath iip = fsDir.getINodesInPath4Write(snapshotRoot);
|
||||||
|
String path = fsNamesys.getSnapshotManager().createSnapshot(iip,
|
||||||
snapshotRoot, createSnapshotOp.snapshotName);
|
snapshotRoot, createSnapshotOp.snapshotName);
|
||||||
if (toAddRetryCache) {
|
if (toAddRetryCache) {
|
||||||
fsNamesys.addCacheEntryWithPayload(createSnapshotOp.rpcClientId,
|
fsNamesys.addCacheEntryWithPayload(createSnapshotOp.rpcClientId,
|
||||||
|
@ -683,8 +684,9 @@ public class FSEditLogLoader {
|
||||||
final String snapshotRoot =
|
final String snapshotRoot =
|
||||||
renameReservedPathsOnUpgrade(deleteSnapshotOp.snapshotRoot,
|
renameReservedPathsOnUpgrade(deleteSnapshotOp.snapshotRoot,
|
||||||
logVersion);
|
logVersion);
|
||||||
|
INodesInPath iip = fsDir.getINodesInPath4Write(snapshotRoot);
|
||||||
fsNamesys.getSnapshotManager().deleteSnapshot(
|
fsNamesys.getSnapshotManager().deleteSnapshot(
|
||||||
snapshotRoot, deleteSnapshotOp.snapshotName,
|
iip, deleteSnapshotOp.snapshotName,
|
||||||
collectedBlocks, removedINodes);
|
collectedBlocks, removedINodes);
|
||||||
fsNamesys.removeBlocksAndUpdateSafemodeTotal(collectedBlocks);
|
fsNamesys.removeBlocksAndUpdateSafemodeTotal(collectedBlocks);
|
||||||
collectedBlocks.clear();
|
collectedBlocks.clear();
|
||||||
|
@ -702,7 +704,8 @@ public class FSEditLogLoader {
|
||||||
final String snapshotRoot =
|
final String snapshotRoot =
|
||||||
renameReservedPathsOnUpgrade(renameSnapshotOp.snapshotRoot,
|
renameReservedPathsOnUpgrade(renameSnapshotOp.snapshotRoot,
|
||||||
logVersion);
|
logVersion);
|
||||||
fsNamesys.getSnapshotManager().renameSnapshot(
|
INodesInPath iip = fsDir.getINodesInPath4Write(snapshotRoot);
|
||||||
|
fsNamesys.getSnapshotManager().renameSnapshot(iip,
|
||||||
snapshotRoot, renameSnapshotOp.snapshotOldName,
|
snapshotRoot, renameSnapshotOp.snapshotOldName,
|
||||||
renameSnapshotOp.snapshotNewName);
|
renameSnapshotOp.snapshotNewName);
|
||||||
|
|
||||||
|
@ -848,9 +851,10 @@ public class FSEditLogLoader {
|
||||||
}
|
}
|
||||||
case OP_SET_STORAGE_POLICY: {
|
case OP_SET_STORAGE_POLICY: {
|
||||||
SetStoragePolicyOp setStoragePolicyOp = (SetStoragePolicyOp) op;
|
SetStoragePolicyOp setStoragePolicyOp = (SetStoragePolicyOp) op;
|
||||||
fsDir.unprotectedSetStoragePolicy(
|
final String path = renameReservedPathsOnUpgrade(setStoragePolicyOp.path,
|
||||||
renameReservedPathsOnUpgrade(setStoragePolicyOp.path, logVersion),
|
logVersion);
|
||||||
setStoragePolicyOp.policyId);
|
final INodesInPath iip = fsDir.getINodesInPath4Write(path);
|
||||||
|
fsDir.unprotectedSetStoragePolicy(iip, setStoragePolicyOp.policyId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1655,11 +1655,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
return sw.toString();
|
return sw.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
long getDefaultBlockSize() {
|
|
||||||
return serverDefaults.getBlockSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
FsServerDefaults getServerDefaults() throws StandbyException {
|
FsServerDefaults getServerDefaults() throws StandbyException {
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
return serverDefaults;
|
return serverDefaults;
|
||||||
|
@ -1682,9 +1677,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
* Set permissions for an existing file.
|
* Set permissions for an existing file.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
void setPermission(String src, FsPermission permission)
|
void setPermission(String src, FsPermission permission) throws IOException {
|
||||||
throws AccessControlException, FileNotFoundException, SafeModeException,
|
|
||||||
UnresolvedLinkException, IOException {
|
|
||||||
try {
|
try {
|
||||||
setPermissionInt(src, permission);
|
setPermissionInt(src, permission);
|
||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
|
@ -1694,8 +1687,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPermissionInt(final String srcArg, FsPermission permission)
|
private void setPermissionInt(final String srcArg, FsPermission permission)
|
||||||
throws AccessControlException, FileNotFoundException, SafeModeException,
|
throws IOException {
|
||||||
UnresolvedLinkException, IOException {
|
|
||||||
String src = srcArg;
|
String src = srcArg;
|
||||||
HdfsFileStatus resultingStat = null;
|
HdfsFileStatus resultingStat = null;
|
||||||
FSPermissionChecker pc = getPermissionChecker();
|
FSPermissionChecker pc = getPermissionChecker();
|
||||||
|
@ -1706,7 +1698,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot set permission for " + src);
|
checkNameNodeSafeMode("Cannot set permission for " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
checkOwner(pc, src);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
dir.checkOwner(pc, iip);
|
||||||
dir.setPermission(src, permission);
|
dir.setPermission(src, permission);
|
||||||
getEditLog().logSetPermissions(src, permission);
|
getEditLog().logSetPermissions(src, permission);
|
||||||
resultingStat = getAuditFileInfo(src, false);
|
resultingStat = getAuditFileInfo(src, false);
|
||||||
|
@ -1722,8 +1715,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
void setOwner(String src, String username, String group)
|
void setOwner(String src, String username, String group)
|
||||||
throws AccessControlException, FileNotFoundException, SafeModeException,
|
throws IOException {
|
||||||
UnresolvedLinkException, IOException {
|
|
||||||
try {
|
try {
|
||||||
setOwnerInt(src, username, group);
|
setOwnerInt(src, username, group);
|
||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
|
@ -1733,8 +1725,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOwnerInt(final String srcArg, String username, String group)
|
private void setOwnerInt(final String srcArg, String username, String group)
|
||||||
throws AccessControlException, FileNotFoundException, SafeModeException,
|
throws IOException {
|
||||||
UnresolvedLinkException, IOException {
|
|
||||||
String src = srcArg;
|
String src = srcArg;
|
||||||
HdfsFileStatus resultingStat = null;
|
HdfsFileStatus resultingStat = null;
|
||||||
FSPermissionChecker pc = getPermissionChecker();
|
FSPermissionChecker pc = getPermissionChecker();
|
||||||
|
@ -1745,7 +1736,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot set owner for " + src);
|
checkNameNodeSafeMode("Cannot set owner for " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
checkOwner(pc, src);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
dir.checkOwner(pc, iip);
|
||||||
if (!pc.isSuperUser()) {
|
if (!pc.isSuperUser()) {
|
||||||
if (username != null && !pc.getUser().equals(username)) {
|
if (username != null && !pc.getUser().equals(username)) {
|
||||||
throw new AccessControlException("Non-super user cannot change owner");
|
throw new AccessControlException("Non-super user cannot change owner");
|
||||||
|
@ -1846,8 +1838,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
*/
|
*/
|
||||||
private LocatedBlocks getBlockLocationsUpdateTimes(final String srcArg,
|
private LocatedBlocks getBlockLocationsUpdateTimes(final String srcArg,
|
||||||
long offset, long length, boolean doAccessTime, boolean needBlockToken)
|
long offset, long length, boolean doAccessTime, boolean needBlockToken)
|
||||||
throws FileNotFoundException,
|
throws IOException {
|
||||||
UnresolvedLinkException, IOException {
|
|
||||||
String src = srcArg;
|
String src = srcArg;
|
||||||
FSPermissionChecker pc = getPermissionChecker();
|
FSPermissionChecker pc = getPermissionChecker();
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
||||||
|
@ -1861,14 +1852,15 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
writeLock(); // writelock is needed to set accesstime
|
writeLock(); // writelock is needed to set accesstime
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
|
||||||
if (isReadOp) {
|
if (isReadOp) {
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
} else {
|
} else {
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
}
|
}
|
||||||
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
|
final INodesInPath iip = dir.getINodesInPath(src, true);
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkPathAccess(pc, src, FsAction.READ);
|
dir.checkPathAccess(pc, iip, FsAction.READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the namenode is in safemode, then do not update access time
|
// if the namenode is in safemode, then do not update access time
|
||||||
|
@ -1876,7 +1868,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
doAccessTime = false;
|
doAccessTime = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final INodesInPath iip = dir.getINodesInPath(src, true);
|
|
||||||
final INode[] inodes = iip.getINodes();
|
final INode[] inodes = iip.getINodes();
|
||||||
final INodeFile inode = INodeFile.valueOf(
|
final INodeFile inode = INodeFile.valueOf(
|
||||||
inodes[inodes.length - 1], src);
|
inodes[inodes.length - 1], src);
|
||||||
|
@ -1985,7 +1976,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTimesInt(final String srcArg, long mtime, long atime)
|
private void setTimesInt(final String srcArg, long mtime, long atime)
|
||||||
throws IOException, UnresolvedLinkException {
|
throws IOException {
|
||||||
String src = srcArg;
|
String src = srcArg;
|
||||||
HdfsFileStatus resultingStat = null;
|
HdfsFileStatus resultingStat = null;
|
||||||
FSPermissionChecker pc = getPermissionChecker();
|
FSPermissionChecker pc = getPermissionChecker();
|
||||||
|
@ -1996,12 +1987,11 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot set times " + src);
|
checkNameNodeSafeMode("Cannot set times " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
// Write access is required to set access and modification times
|
// Write access is required to set access and modification times
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkPathAccess(pc, src, FsAction.WRITE);
|
dir.checkPathAccess(pc, iip, FsAction.WRITE);
|
||||||
}
|
}
|
||||||
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
|
||||||
final INode inode = iip.getLastINode();
|
final INode inode = iip.getLastINode();
|
||||||
if (inode != null) {
|
if (inode != null) {
|
||||||
boolean changed = dir.setTimes(inode, mtime, atime, true,
|
boolean changed = dir.setTimes(inode, mtime, atime, true,
|
||||||
|
@ -2025,7 +2015,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
void createSymlink(String target, String link,
|
void createSymlink(String target, String link,
|
||||||
PermissionStatus dirPerms, boolean createParent, boolean logRetryCache)
|
PermissionStatus dirPerms, boolean createParent, boolean logRetryCache)
|
||||||
throws IOException, UnresolvedLinkException {
|
throws IOException {
|
||||||
if (!FileSystem.areSymlinksEnabled()) {
|
if (!FileSystem.areSymlinksEnabled()) {
|
||||||
throw new UnsupportedOperationException("Symlinks not supported");
|
throw new UnsupportedOperationException("Symlinks not supported");
|
||||||
}
|
}
|
||||||
|
@ -2036,10 +2026,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
throw new InvalidPathException("Invalid target name: " + target);
|
throw new InvalidPathException("Invalid target name: " + target);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean success = false;
|
|
||||||
try {
|
try {
|
||||||
createSymlinkInt(target, link, dirPerms, createParent, logRetryCache);
|
createSymlinkInt(target, link, dirPerms, createParent, logRetryCache);
|
||||||
success = true;
|
|
||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
logAuditEvent(false, "createSymlink", link, target, null);
|
logAuditEvent(false, "createSymlink", link, target, null);
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -2048,7 +2036,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
|
|
||||||
private void createSymlinkInt(String target, final String linkArg,
|
private void createSymlinkInt(String target, final String linkArg,
|
||||||
PermissionStatus dirPerms, boolean createParent, boolean logRetryCache)
|
PermissionStatus dirPerms, boolean createParent, boolean logRetryCache)
|
||||||
throws IOException, UnresolvedLinkException {
|
throws IOException {
|
||||||
String link = linkArg;
|
String link = linkArg;
|
||||||
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
||||||
NameNode.stateChangeLog.debug("DIR* NameSystem.createSymlink: target="
|
NameNode.stateChangeLog.debug("DIR* NameSystem.createSymlink: target="
|
||||||
|
@ -2063,15 +2051,16 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot create symlink " + link);
|
checkNameNodeSafeMode("Cannot create symlink " + link);
|
||||||
link = dir.resolvePath(pc, link, pathComponents);
|
link = dir.resolvePath(pc, link, pathComponents);
|
||||||
|
final INodesInPath iip = dir.getINodesInPath4Write(link, false);
|
||||||
if (!createParent) {
|
if (!createParent) {
|
||||||
dir.verifyParentDir(link);
|
dir.verifyParentDir(iip, link);
|
||||||
}
|
}
|
||||||
if (!dir.isValidToCreate(link)) {
|
if (!dir.isValidToCreate(link)) {
|
||||||
throw new IOException("failed to create link " + link
|
throw new IOException("failed to create link " + link
|
||||||
+" either because the filename is invalid or the file exists");
|
+" either because the filename is invalid or the file exists");
|
||||||
}
|
}
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkAncestorAccess(pc, link, FsAction.WRITE);
|
dir.checkAncestorAccess(pc, iip, FsAction.WRITE);
|
||||||
}
|
}
|
||||||
// validate that we have enough inodes.
|
// validate that we have enough inodes.
|
||||||
checkFsObjectLimit();
|
checkFsObjectLimit();
|
||||||
|
@ -2123,8 +2112,9 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot set replication for " + src);
|
checkNameNodeSafeMode("Cannot set replication for " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkPathAccess(pc, src, FsAction.WRITE);
|
dir.checkPathAccess(pc, iip, FsAction.WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
final short[] blockRepls = new short[2]; // 0: old, 1: new
|
final short[] blockRepls = new short[2]; // 0: old, 1: new
|
||||||
|
@ -2162,8 +2152,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setStoragePolicyInt(String src, final String policyName)
|
private void setStoragePolicyInt(String src, final String policyName)
|
||||||
throws IOException, UnresolvedLinkException, AccessControlException {
|
throws IOException {
|
||||||
|
|
||||||
if (!isStoragePolicyEnabled) {
|
if (!isStoragePolicyEnabled) {
|
||||||
throw new IOException("Failed to set storage policy since "
|
throw new IOException("Failed to set storage policy since "
|
||||||
+ DFS_STORAGE_POLICY_ENABLED_KEY + " is set to false.");
|
+ DFS_STORAGE_POLICY_ENABLED_KEY + " is set to false.");
|
||||||
|
@ -2182,12 +2171,12 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot set storage policy for " + src);
|
checkNameNodeSafeMode("Cannot set storage policy for " + src);
|
||||||
|
|
||||||
if (pc != null) {
|
|
||||||
checkPermission(pc, src, false, null, null, FsAction.WRITE, null,
|
|
||||||
false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
||||||
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
|
||||||
|
if (pc != null) {
|
||||||
|
dir.checkPermission(pc, iip, false, null, null, FsAction.WRITE, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
// get the corresponding policy and make sure the policy name is valid
|
// get the corresponding policy and make sure the policy name is valid
|
||||||
BlockStoragePolicy policy = blockManager.getStoragePolicy(policyName);
|
BlockStoragePolicy policy = blockManager.getStoragePolicy(policyName);
|
||||||
|
@ -2195,7 +2184,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
throw new HadoopIllegalArgumentException(
|
throw new HadoopIllegalArgumentException(
|
||||||
"Cannot find a block policy with the name " + policyName);
|
"Cannot find a block policy with the name " + policyName);
|
||||||
}
|
}
|
||||||
dir.setStoragePolicy(src, policy.getId());
|
dir.setStoragePolicy(iip, policy.getId());
|
||||||
getEditLog().logSetStoragePolicy(src, policy.getId());
|
getEditLog().logSetStoragePolicy(src, policy.getId());
|
||||||
fileStat = getAuditFileInfo(src, false);
|
fileStat = getAuditFileInfo(src, false);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -2221,8 +2210,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long getPreferredBlockSize(String filename)
|
long getPreferredBlockSize(String filename) throws IOException {
|
||||||
throws IOException, UnresolvedLinkException {
|
|
||||||
FSPermissionChecker pc = getPermissionChecker();
|
FSPermissionChecker pc = getPermissionChecker();
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(filename);
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(filename);
|
||||||
|
@ -2230,8 +2218,9 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
try {
|
try {
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
filename = dir.resolvePath(pc, filename, pathComponents);
|
filename = dir.resolvePath(pc, filename, pathComponents);
|
||||||
|
final INodesInPath iip = dir.getINodesInPath(filename, true);
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkTraverse(pc, filename);
|
dir.checkTraverse(pc, iip);
|
||||||
}
|
}
|
||||||
return dir.getPreferredBlockSize(filename);
|
return dir.getPreferredBlockSize(filename);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -2432,7 +2421,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot create file" + src);
|
checkNameNodeSafeMode("Cannot create file" + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
toRemoveBlocks = startFileInternal(pc, src, permissions, holder,
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
toRemoveBlocks = startFileInternal(pc, iip, permissions, holder,
|
||||||
clientMachine, create, overwrite, createParent, replication,
|
clientMachine, create, overwrite, createParent, replication,
|
||||||
blockSize, isLazyPersist, suite, protocolVersion, edek, logRetryCache);
|
blockSize, isLazyPersist, suite, protocolVersion, edek, logRetryCache);
|
||||||
stat = FSDirStatAndListingOp.getFileInfo(dir, src, false,
|
stat = FSDirStatAndListingOp.getFileInfo(dir, src, false,
|
||||||
|
@ -2467,23 +2457,36 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
* {@link ClientProtocol#create}
|
* {@link ClientProtocol#create}
|
||||||
*/
|
*/
|
||||||
private BlocksMapUpdateInfo startFileInternal(FSPermissionChecker pc,
|
private BlocksMapUpdateInfo startFileInternal(FSPermissionChecker pc,
|
||||||
String src, PermissionStatus permissions, String holder,
|
INodesInPath iip, PermissionStatus permissions, String holder,
|
||||||
String clientMachine, boolean create, boolean overwrite,
|
String clientMachine, boolean create, boolean overwrite,
|
||||||
boolean createParent, short replication, long blockSize,
|
boolean createParent, short replication, long blockSize,
|
||||||
boolean isLazyPersist, CipherSuite suite, CryptoProtocolVersion version,
|
boolean isLazyPersist, CipherSuite suite, CryptoProtocolVersion version,
|
||||||
EncryptedKeyVersion edek, boolean logRetryEntry)
|
EncryptedKeyVersion edek, boolean logRetryEntry)
|
||||||
throws FileAlreadyExistsException, AccessControlException,
|
throws IOException {
|
||||||
UnresolvedLinkException, FileNotFoundException,
|
|
||||||
ParentNotDirectoryException, RetryStartFileException, IOException {
|
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
// Verify that the destination does not exist as a directory already.
|
// Verify that the destination does not exist as a directory already.
|
||||||
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
|
||||||
final INode inode = iip.getLastINode();
|
final INode inode = iip.getLastINode();
|
||||||
|
final String src = iip.getPath();
|
||||||
if (inode != null && inode.isDirectory()) {
|
if (inode != null && inode.isDirectory()) {
|
||||||
throw new FileAlreadyExistsException(src +
|
throw new FileAlreadyExistsException(src +
|
||||||
" already exists as a directory");
|
" already exists as a directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final INodeFile myFile = INodeFile.valueOf(inode, src, true);
|
||||||
|
if (isPermissionEnabled) {
|
||||||
|
if (overwrite && myFile != null) {
|
||||||
|
dir.checkPathAccess(pc, iip, FsAction.WRITE);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* To overwrite existing file, need to check 'w' permission
|
||||||
|
* of parent (equals to ancestor in this case)
|
||||||
|
*/
|
||||||
|
dir.checkAncestorAccess(pc, iip, FsAction.WRITE);
|
||||||
|
}
|
||||||
|
if (!createParent) {
|
||||||
|
dir.verifyParentDir(iip, src);
|
||||||
|
}
|
||||||
|
|
||||||
FileEncryptionInfo feInfo = null;
|
FileEncryptionInfo feInfo = null;
|
||||||
|
|
||||||
final EncryptionZone zone = dir.getEZForPath(iip);
|
final EncryptionZone zone = dir.getEZForPath(iip);
|
||||||
|
@ -2504,22 +2507,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
ezKeyName, edek.getEncryptionKeyVersionName());
|
ezKeyName, edek.getEncryptionKeyVersionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
final INodeFile myFile = INodeFile.valueOf(inode, src, true);
|
|
||||||
if (isPermissionEnabled) {
|
|
||||||
if (overwrite && myFile != null) {
|
|
||||||
checkPathAccess(pc, src, FsAction.WRITE);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* To overwrite existing file, need to check 'w' permission
|
|
||||||
* of parent (equals to ancestor in this case)
|
|
||||||
*/
|
|
||||||
checkAncestorAccess(pc, src, FsAction.WRITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!createParent) {
|
|
||||||
dir.verifyParentDir(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BlocksMapUpdateInfo toRemoveBlocks = null;
|
BlocksMapUpdateInfo toRemoveBlocks = null;
|
||||||
if (myFile == null) {
|
if (myFile == null) {
|
||||||
|
@ -2631,20 +2618,19 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
*
|
*
|
||||||
* @return the last block locations if the block is partial or null otherwise
|
* @return the last block locations if the block is partial or null otherwise
|
||||||
*/
|
*/
|
||||||
private LocatedBlock appendFileInternal(FSPermissionChecker pc, String src,
|
private LocatedBlock appendFileInternal(FSPermissionChecker pc,
|
||||||
String holder, String clientMachine, boolean logRetryCache)
|
INodesInPath iip, String holder, String clientMachine,
|
||||||
throws AccessControlException, UnresolvedLinkException,
|
boolean logRetryCache) throws IOException {
|
||||||
FileNotFoundException, IOException {
|
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
// Verify that the destination does not exist as a directory already.
|
// Verify that the destination does not exist as a directory already.
|
||||||
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
|
||||||
final INode inode = iip.getLastINode();
|
final INode inode = iip.getLastINode();
|
||||||
|
final String src = iip.getPath();
|
||||||
if (inode != null && inode.isDirectory()) {
|
if (inode != null && inode.isDirectory()) {
|
||||||
throw new FileAlreadyExistsException("Cannot append to directory " + src
|
throw new FileAlreadyExistsException("Cannot append to directory " + src
|
||||||
+ "; already exists as a directory.");
|
+ "; already exists as a directory.");
|
||||||
}
|
}
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkPathAccess(pc, src, FsAction.WRITE);
|
dir.checkPathAccess(pc, iip, FsAction.WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -2748,12 +2734,13 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot recover the lease of " + src);
|
checkNameNodeSafeMode("Cannot recover the lease of " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
final INodeFile inode = INodeFile.valueOf(dir.getINode(src), src);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
final INodeFile inode = INodeFile.valueOf(iip.getLastINode(), src);
|
||||||
if (!inode.isUnderConstruction()) {
|
if (!inode.isUnderConstruction()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkPathAccess(pc, src, FsAction.WRITE);
|
dir.checkPathAccess(pc, iip, FsAction.WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
recoverLeaseInternal(inode, src, holder, clientMachine, true);
|
recoverLeaseInternal(inode, src, holder, clientMachine, true);
|
||||||
|
@ -2889,7 +2876,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot append to file" + src);
|
checkNameNodeSafeMode("Cannot append to file" + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
lb = appendFileInternal(pc, src, holder, clientMachine, logRetryCache);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
lb = appendFileInternal(pc, iip, holder, clientMachine, logRetryCache);
|
||||||
stat = FSDirStatAndListingOp.getFileInfo(dir, src, false,
|
stat = FSDirStatAndListingOp.getFileInfo(dir, src, false,
|
||||||
FSDirectory.isReservedRawName(srcArg), true);
|
FSDirectory.isReservedRawName(srcArg), true);
|
||||||
} catch (StandbyException se) {
|
} catch (StandbyException se) {
|
||||||
|
@ -3525,7 +3513,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the indicated filename.
|
* Change the indicated filename.
|
||||||
* @deprecated Use {@link #renameTo(String, String, Options.Rename...)} instead.
|
* @deprecated Use {@link #renameTo(String, String, boolean,
|
||||||
|
* Options.Rename...)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
boolean renameTo(String src, String dst, boolean logRetryCache)
|
boolean renameTo(String src, String dst, boolean logRetryCache)
|
||||||
|
@ -3651,12 +3640,13 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot delete " + src);
|
checkNameNodeSafeMode("Cannot delete " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
if (!recursive && dir.isNonEmptyDirectory(src)) {
|
final INodesInPath iip = dir.getINodesInPath4Write(src, false);
|
||||||
|
if (!recursive && dir.isNonEmptyDirectory(iip)) {
|
||||||
throw new PathIsNotEmptyDirectoryException(src + " is non empty");
|
throw new PathIsNotEmptyDirectoryException(src + " is non empty");
|
||||||
}
|
}
|
||||||
if (enforcePermission && isPermissionEnabled) {
|
if (enforcePermission && isPermissionEnabled) {
|
||||||
checkPermission(pc, src, false, null, FsAction.WRITE, null,
|
dir.checkPermission(pc, iip, false, null, FsAction.WRITE, null,
|
||||||
FsAction.ALL, true, false);
|
FsAction.ALL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
long mtime = now();
|
long mtime = now();
|
||||||
|
@ -3794,7 +3784,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
/**
|
/**
|
||||||
* Get the file info for a specific file.
|
* Get the file info for a specific file.
|
||||||
*
|
*
|
||||||
* @param srcArg The string representation of the path to the file
|
* @param src The string representation of the path to the file
|
||||||
* @param resolveLink whether to throw UnresolvedLinkException
|
* @param resolveLink whether to throw UnresolvedLinkException
|
||||||
* if src refers to a symlink
|
* if src refers to a symlink
|
||||||
*
|
*
|
||||||
|
@ -5834,17 +5824,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
return new PermissionStatus(fsOwner.getShortUserName(), supergroup, permission);
|
return new PermissionStatus(fsOwner.getShortUserName(), supergroup, permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkOwner(FSPermissionChecker pc, String path)
|
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
|
||||||
dir.checkOwner(pc, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkPathAccess(FSPermissionChecker pc,
|
|
||||||
String path, FsAction access) throws AccessControlException,
|
|
||||||
UnresolvedLinkException {
|
|
||||||
dir.checkPathAccess(pc, path, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkUnreadableBySuperuser(FSPermissionChecker pc,
|
private void checkUnreadableBySuperuser(FSPermissionChecker pc,
|
||||||
INode inode, int snapshotId)
|
INode inode, int snapshotId)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
@ -5860,23 +5839,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkParentAccess(FSPermissionChecker pc,
|
|
||||||
String path, FsAction access) throws AccessControlException,
|
|
||||||
UnresolvedLinkException {
|
|
||||||
dir.checkParentAccess(pc, path, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkAncestorAccess(FSPermissionChecker pc,
|
|
||||||
String path, FsAction access) throws AccessControlException,
|
|
||||||
UnresolvedLinkException {
|
|
||||||
dir.checkAncestorAccess(pc, path, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkTraverse(FSPermissionChecker pc, String path)
|
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
|
||||||
dir.checkTraverse(pc, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkSuperuserPrivilege()
|
public void checkSuperuserPrivilege()
|
||||||
throws AccessControlException {
|
throws AccessControlException {
|
||||||
|
@ -5886,28 +5848,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether current user have permissions to access the path. For more
|
|
||||||
* details of the parameters, see
|
|
||||||
* {@link FSPermissionChecker#checkPermission}.
|
|
||||||
*/
|
|
||||||
private void checkPermission(FSPermissionChecker pc,
|
|
||||||
String path, boolean doCheckOwner, FsAction ancestorAccess,
|
|
||||||
FsAction parentAccess, FsAction access, FsAction subAccess)
|
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
|
||||||
checkPermission(pc, path, doCheckOwner, ancestorAccess,
|
|
||||||
parentAccess, access, subAccess, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkPermission(FSPermissionChecker pc,
|
|
||||||
String path, boolean doCheckOwner, FsAction ancestorAccess,
|
|
||||||
FsAction parentAccess, FsAction access, FsAction subAccess,
|
|
||||||
boolean ignoreEmptyDir, boolean resolveLink)
|
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
|
||||||
dir.checkPermission(pc, path, doCheckOwner, ancestorAccess, parentAccess,
|
|
||||||
access, subAccess, ignoreEmptyDir, resolveLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if we have exceeded the limit on the number
|
* Check to see if we have exceeded the limit on the number
|
||||||
* of inodes.
|
* of inodes.
|
||||||
|
@ -6299,9 +6239,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
+ newBlock.getLocalBlock() + ") success");
|
+ newBlock.getLocalBlock() + ") success");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see #updatePipeline(String, ExtendedBlock, ExtendedBlock, DatanodeID[], String[])
|
|
||||||
*/
|
|
||||||
private void updatePipelineInternal(String clientName, ExtendedBlock oldBlock,
|
private void updatePipelineInternal(String clientName, ExtendedBlock oldBlock,
|
||||||
ExtendedBlock newBlock, DatanodeID[] newNodes, String[] newStorageIDs,
|
ExtendedBlock newBlock, DatanodeID[] newNodes, String[] newStorageIDs,
|
||||||
boolean logRetryCache)
|
boolean logRetryCache)
|
||||||
|
@ -7387,9 +7324,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
* @throws SafeModeException
|
* @throws SafeModeException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
void deleteSnapshot(
|
void deleteSnapshot(String snapshotRoot, String snapshotName,
|
||||||
String snapshotRoot, String snapshotName, boolean logRetryCache)
|
boolean logRetryCache) throws IOException {
|
||||||
throws IOException {
|
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
writeLock();
|
writeLock();
|
||||||
|
@ -7397,6 +7333,7 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
try {
|
try {
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot delete snapshot for " + snapshotRoot);
|
checkNameNodeSafeMode("Cannot delete snapshot for " + snapshotRoot);
|
||||||
|
|
||||||
blocksToBeDeleted = FSDirSnapshotOp.deleteSnapshot(dir, snapshotManager,
|
blocksToBeDeleted = FSDirSnapshotOp.deleteSnapshot(dir, snapshotManager,
|
||||||
snapshotRoot, snapshotName, logRetryCache);
|
snapshotRoot, snapshotName, logRetryCache);
|
||||||
success = true;
|
success = true;
|
||||||
|
@ -7855,7 +7792,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot modify ACL entries on " + src);
|
checkNameNodeSafeMode("Cannot modify ACL entries on " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
checkOwner(pc, src);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
dir.checkOwner(pc, iip);
|
||||||
List<AclEntry> newAcl = dir.modifyAclEntries(src, aclSpec);
|
List<AclEntry> newAcl = dir.modifyAclEntries(src, aclSpec);
|
||||||
getEditLog().logSetAcl(src, newAcl);
|
getEditLog().logSetAcl(src, newAcl);
|
||||||
resultingStat = getAuditFileInfo(src, false);
|
resultingStat = getAuditFileInfo(src, false);
|
||||||
|
@ -7882,7 +7820,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot remove ACL entries on " + src);
|
checkNameNodeSafeMode("Cannot remove ACL entries on " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
checkOwner(pc, src);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
dir.checkOwner(pc, iip);
|
||||||
List<AclEntry> newAcl = dir.removeAclEntries(src, aclSpec);
|
List<AclEntry> newAcl = dir.removeAclEntries(src, aclSpec);
|
||||||
getEditLog().logSetAcl(src, newAcl);
|
getEditLog().logSetAcl(src, newAcl);
|
||||||
resultingStat = getAuditFileInfo(src, false);
|
resultingStat = getAuditFileInfo(src, false);
|
||||||
|
@ -7908,7 +7847,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot remove default ACL entries on " + src);
|
checkNameNodeSafeMode("Cannot remove default ACL entries on " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
checkOwner(pc, src);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
dir.checkOwner(pc, iip);
|
||||||
List<AclEntry> newAcl = dir.removeDefaultAcl(src);
|
List<AclEntry> newAcl = dir.removeDefaultAcl(src);
|
||||||
getEditLog().logSetAcl(src, newAcl);
|
getEditLog().logSetAcl(src, newAcl);
|
||||||
resultingStat = getAuditFileInfo(src, false);
|
resultingStat = getAuditFileInfo(src, false);
|
||||||
|
@ -7934,7 +7874,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot remove ACL on " + src);
|
checkNameNodeSafeMode("Cannot remove ACL on " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
checkOwner(pc, src);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
dir.checkOwner(pc, iip);
|
||||||
dir.removeAcl(src);
|
dir.removeAcl(src);
|
||||||
getEditLog().logSetAcl(src, AclFeature.EMPTY_ENTRY_LIST);
|
getEditLog().logSetAcl(src, AclFeature.EMPTY_ENTRY_LIST);
|
||||||
resultingStat = getAuditFileInfo(src, false);
|
resultingStat = getAuditFileInfo(src, false);
|
||||||
|
@ -7960,7 +7901,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot set ACL on " + src);
|
checkNameNodeSafeMode("Cannot set ACL on " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
checkOwner(pc, src);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
dir.checkOwner(pc, iip);
|
||||||
List<AclEntry> newAcl = dir.setAcl(src, aclSpec);
|
List<AclEntry> newAcl = dir.setAcl(src, aclSpec);
|
||||||
getEditLog().logSetAcl(src, newAcl);
|
getEditLog().logSetAcl(src, newAcl);
|
||||||
resultingStat = getAuditFileInfo(src, false);
|
resultingStat = getAuditFileInfo(src, false);
|
||||||
|
@ -7984,8 +7926,9 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
try {
|
try {
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
|
INodesInPath iip = dir.getINodesInPath(src, true);
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkPermission(pc, src, false, null, null, null, null);
|
dir.checkPermission(pc, iip, false, null, null, null, null);
|
||||||
}
|
}
|
||||||
final AclStatus ret = dir.getAclStatus(src);
|
final AclStatus ret = dir.getAclStatus(src);
|
||||||
success = true;
|
success = true;
|
||||||
|
@ -8095,12 +8038,12 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
readLock();
|
readLock();
|
||||||
try {
|
try {
|
||||||
if (isPermissionEnabled) {
|
|
||||||
checkPathAccess(pc, src, FsAction.READ);
|
|
||||||
}
|
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
final INodesInPath iip = dir.getINodesInPath(src, true);
|
final INodesInPath iip = dir.getINodesInPath(src, true);
|
||||||
|
if (isPermissionEnabled) {
|
||||||
|
dir.checkPathAccess(pc, iip, FsAction.READ);
|
||||||
|
}
|
||||||
final EncryptionZone ret = dir.getEZForPath(iip);
|
final EncryptionZone ret = dir.getEZForPath(iip);
|
||||||
resultingStat = getAuditFileInfo(src, false);
|
resultingStat = getAuditFileInfo(src, false);
|
||||||
success = true;
|
success = true;
|
||||||
|
@ -8172,7 +8115,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot set XAttr on " + src);
|
checkNameNodeSafeMode("Cannot set XAttr on " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
checkXAttrChangeAccess(src, xAttr, pc);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
checkXAttrChangeAccess(iip, xAttr, pc);
|
||||||
List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1);
|
List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1);
|
||||||
xAttrs.add(xAttr);
|
xAttrs.add(xAttr);
|
||||||
dir.setXAttrs(src, xAttrs, flag);
|
dir.setXAttrs(src, xAttrs, flag);
|
||||||
|
@ -8224,10 +8168,11 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
||||||
readLock();
|
readLock();
|
||||||
try {
|
try {
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
|
final INodesInPath iip = dir.getINodesInPath(src, true);
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkPathAccess(pc, src, FsAction.READ);
|
dir.checkPathAccess(pc, iip, FsAction.READ);
|
||||||
}
|
}
|
||||||
List<XAttr> all = dir.getXAttrs(src);
|
List<XAttr> all = dir.getXAttrs(src);
|
||||||
List<XAttr> filteredAll = XAttrPermissionFilter.
|
List<XAttr> filteredAll = XAttrPermissionFilter.
|
||||||
|
@ -8272,16 +8217,16 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
||||||
readLock();
|
readLock();
|
||||||
try {
|
try {
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
|
final INodesInPath iip = dir.getINodesInPath(src, true);
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
/* To access xattr names, you need EXECUTE in the owning directory. */
|
/* To access xattr names, you need EXECUTE in the owning directory. */
|
||||||
checkParentAccess(pc, src, FsAction.EXECUTE);
|
dir.checkParentAccess(pc, iip, FsAction.EXECUTE);
|
||||||
}
|
}
|
||||||
final List<XAttr> all = dir.getXAttrs(src);
|
final List<XAttr> all = dir.getXAttrs(src);
|
||||||
final List<XAttr> filteredAll = XAttrPermissionFilter.
|
return XAttrPermissionFilter.
|
||||||
filterXAttrsForApi(pc, all, isRawPath);
|
filterXAttrsForApi(pc, all, isRawPath);
|
||||||
return filteredAll;
|
|
||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
logAuditEvent(false, "listXAttrs", src);
|
logAuditEvent(false, "listXAttrs", src);
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -8327,7 +8272,8 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
checkOperation(OperationCategory.WRITE);
|
checkOperation(OperationCategory.WRITE);
|
||||||
checkNameNodeSafeMode("Cannot remove XAttr entry on " + src);
|
checkNameNodeSafeMode("Cannot remove XAttr entry on " + src);
|
||||||
src = dir.resolvePath(pc, src, pathComponents);
|
src = dir.resolvePath(pc, src, pathComponents);
|
||||||
checkXAttrChangeAccess(src, xAttr, pc);
|
final INodesInPath iip = dir.getINodesInPath4Write(src);
|
||||||
|
checkXAttrChangeAccess(iip, xAttr, pc);
|
||||||
|
|
||||||
List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1);
|
List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1);
|
||||||
xAttrs.add(xAttr);
|
xAttrs.add(xAttr);
|
||||||
|
@ -8346,37 +8292,37 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
logAuditEvent(true, "removeXAttr", srcArg, null, resultingStat);
|
logAuditEvent(true, "removeXAttr", srcArg, null, resultingStat);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkXAttrChangeAccess(String src, XAttr xAttr,
|
private void checkXAttrChangeAccess(INodesInPath iip, XAttr xAttr,
|
||||||
FSPermissionChecker pc) throws UnresolvedLinkException,
|
FSPermissionChecker pc) throws AccessControlException {
|
||||||
AccessControlException {
|
|
||||||
if (isPermissionEnabled && xAttr.getNameSpace() == XAttr.NameSpace.USER) {
|
if (isPermissionEnabled && xAttr.getNameSpace() == XAttr.NameSpace.USER) {
|
||||||
final INode inode = dir.getINode(src);
|
final INode inode = iip.getLastINode();
|
||||||
if (inode != null &&
|
if (inode != null &&
|
||||||
inode.isDirectory() &&
|
inode.isDirectory() &&
|
||||||
inode.getFsPermission().getStickyBit()) {
|
inode.getFsPermission().getStickyBit()) {
|
||||||
if (!pc.isSuperUser()) {
|
if (!pc.isSuperUser()) {
|
||||||
checkOwner(pc, src);
|
dir.checkOwner(pc, iip);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
checkPathAccess(pc, src, FsAction.WRITE);
|
dir.checkPathAccess(pc, iip, FsAction.WRITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAccess(String src, FsAction mode) throws AccessControlException,
|
void checkAccess(String src, FsAction mode) throws IOException {
|
||||||
FileNotFoundException, UnresolvedLinkException, IOException {
|
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
||||||
readLock();
|
readLock();
|
||||||
try {
|
try {
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
||||||
if (dir.getINode(src) == null) {
|
final INodesInPath iip = dir.getINodesInPath(src, true);
|
||||||
|
INode[] inodes = iip.getINodes();
|
||||||
|
if (inodes[inodes.length - 1] == null) {
|
||||||
throw new FileNotFoundException("Path not found");
|
throw new FileNotFoundException("Path not found");
|
||||||
}
|
}
|
||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
FSPermissionChecker pc = getPermissionChecker();
|
FSPermissionChecker pc = getPermissionChecker();
|
||||||
checkPathAccess(pc, src, mode);
|
dir.checkPathAccess(pc, iip, mode);
|
||||||
}
|
}
|
||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
logAuditEvent(false, "checkAccess", src);
|
logAuditEvent(false, "checkAccess", src);
|
||||||
|
|
|
@ -25,7 +25,6 @@ import java.util.Stack;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.fs.UnresolvedLinkException;
|
|
||||||
import org.apache.hadoop.fs.permission.AclEntryScope;
|
import org.apache.hadoop.fs.permission.AclEntryScope;
|
||||||
import org.apache.hadoop.fs.permission.AclEntryType;
|
import org.apache.hadoop.fs.permission.AclEntryType;
|
||||||
import org.apache.hadoop.fs.permission.FsAction;
|
import org.apache.hadoop.fs.permission.FsAction;
|
||||||
|
@ -58,7 +57,6 @@ class FSPermissionChecker {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final UserGroupInformation ugi;
|
|
||||||
private final String user;
|
private final String user;
|
||||||
/** A set with group namess. Not synchronized since it is unmodifiable */
|
/** A set with group namess. Not synchronized since it is unmodifiable */
|
||||||
private final Set<String> groups;
|
private final Set<String> groups;
|
||||||
|
@ -66,10 +64,9 @@ class FSPermissionChecker {
|
||||||
|
|
||||||
FSPermissionChecker(String fsOwner, String supergroup,
|
FSPermissionChecker(String fsOwner, String supergroup,
|
||||||
UserGroupInformation callerUgi) {
|
UserGroupInformation callerUgi) {
|
||||||
ugi = callerUgi;
|
HashSet<String> s = new HashSet<String>(Arrays.asList(callerUgi.getGroupNames()));
|
||||||
HashSet<String> s = new HashSet<String>(Arrays.asList(ugi.getGroupNames()));
|
|
||||||
groups = Collections.unmodifiableSet(s);
|
groups = Collections.unmodifiableSet(s);
|
||||||
user = ugi.getShortUserName();
|
user = callerUgi.getShortUserName();
|
||||||
isSuper = user.equals(fsOwner) || groups.contains(supergroup);
|
isSuper = user.equals(fsOwner) || groups.contains(supergroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,18 +123,15 @@ class FSPermissionChecker {
|
||||||
* it is the access required of the path and all the sub-directories.
|
* it is the access required of the path and all the sub-directories.
|
||||||
* If path is not a directory, there is no effect.
|
* If path is not a directory, there is no effect.
|
||||||
* @param ignoreEmptyDir Ignore permission checking for empty directory?
|
* @param ignoreEmptyDir Ignore permission checking for empty directory?
|
||||||
* @param resolveLink whether to resolve the final path component if it is
|
|
||||||
* a symlink
|
|
||||||
* @throws AccessControlException
|
* @throws AccessControlException
|
||||||
* @throws UnresolvedLinkException
|
|
||||||
*
|
*
|
||||||
* 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, FSDirectory dir, boolean doCheckOwner,
|
void checkPermission(INodesInPath inodesInPath, boolean doCheckOwner,
|
||||||
FsAction ancestorAccess, FsAction parentAccess, FsAction access,
|
FsAction ancestorAccess, FsAction parentAccess, FsAction access,
|
||||||
FsAction subAccess, boolean ignoreEmptyDir, boolean resolveLink)
|
FsAction subAccess, boolean ignoreEmptyDir)
|
||||||
throws AccessControlException, UnresolvedLinkException {
|
throws AccessControlException {
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("ACCESS CHECK: " + this
|
LOG.debug("ACCESS CHECK: " + this
|
||||||
+ ", doCheckOwner=" + doCheckOwner
|
+ ", doCheckOwner=" + doCheckOwner
|
||||||
|
@ -145,12 +139,10 @@ class FSPermissionChecker {
|
||||||
+ ", parentAccess=" + parentAccess
|
+ ", parentAccess=" + parentAccess
|
||||||
+ ", access=" + access
|
+ ", access=" + access
|
||||||
+ ", subAccess=" + subAccess
|
+ ", subAccess=" + subAccess
|
||||||
+ ", ignoreEmptyDir=" + ignoreEmptyDir
|
+ ", ignoreEmptyDir=" + ignoreEmptyDir);
|
||||||
+ ", resolveLink=" + resolveLink);
|
|
||||||
}
|
}
|
||||||
// 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 = 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;
|
||||||
|
|
|
@ -41,8 +41,8 @@ public class INodesInPath {
|
||||||
* @return true if path component is {@link HdfsConstants#DOT_SNAPSHOT_DIR}
|
* @return true if path component is {@link HdfsConstants#DOT_SNAPSHOT_DIR}
|
||||||
*/
|
*/
|
||||||
private static boolean isDotSnapshotDir(byte[] pathComponent) {
|
private static boolean isDotSnapshotDir(byte[] pathComponent) {
|
||||||
return pathComponent == null ? false
|
return pathComponent != null &&
|
||||||
: Arrays.equals(HdfsConstants.DOT_SNAPSHOT_DIR_BYTES, pathComponent);
|
Arrays.equals(HdfsConstants.DOT_SNAPSHOT_DIR_BYTES, pathComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static INodesInPath fromINode(INode inode) {
|
static INodesInPath fromINode(INode inode) {
|
||||||
|
@ -177,7 +177,7 @@ public class INodesInPath {
|
||||||
(dstSnapshotId != Snapshot.CURRENT_STATE_ID &&
|
(dstSnapshotId != Snapshot.CURRENT_STATE_ID &&
|
||||||
dstSnapshotId >= latest)) { // the above scenario
|
dstSnapshotId >= latest)) { // the above scenario
|
||||||
int lastSnapshot = Snapshot.CURRENT_STATE_ID;
|
int lastSnapshot = Snapshot.CURRENT_STATE_ID;
|
||||||
DirectoryWithSnapshotFeature sf = null;
|
DirectoryWithSnapshotFeature sf;
|
||||||
if (curNode.isDirectory() &&
|
if (curNode.isDirectory() &&
|
||||||
(sf = curNode.asDirectory().getDirectoryWithSnapshotFeature()) != null) {
|
(sf = curNode.asDirectory().getDirectoryWithSnapshotFeature()) != null) {
|
||||||
lastSnapshot = sf.getLastSnapshotId();
|
lastSnapshot = sf.getLastSnapshotId();
|
||||||
|
@ -186,7 +186,7 @@ public class INodesInPath {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curNode.isSymlink() && (!lastComp || (lastComp && resolveLink))) {
|
if (curNode.isSymlink() && (!lastComp || resolveLink)) {
|
||||||
final String path = constructPath(components, 0, components.length);
|
final String path = constructPath(components, 0, components.length);
|
||||||
final String preceding = constructPath(components, 0, count);
|
final String preceding = constructPath(components, 0, count);
|
||||||
final String remainder =
|
final String remainder =
|
||||||
|
@ -207,7 +207,7 @@ public class INodesInPath {
|
||||||
final byte[] childName = components[count + 1];
|
final byte[] childName = components[count + 1];
|
||||||
|
|
||||||
// check if the next byte[] in components is for ".snapshot"
|
// check if the next byte[] in components is for ".snapshot"
|
||||||
if (isDotSnapshotDir(childName) && isDir && dir.isSnapshottable()) {
|
if (isDotSnapshotDir(childName) && dir.isSnapshottable()) {
|
||||||
// skip the ".snapshot" in components
|
// skip the ".snapshot" in components
|
||||||
count++;
|
count++;
|
||||||
index++;
|
index++;
|
||||||
|
@ -345,6 +345,11 @@ public class INodesInPath {
|
||||||
return path[path.length - 1];
|
return path[path.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the full path in string form */
|
||||||
|
public String getPath() {
|
||||||
|
return DFSUtil.byteArray2PathString(path);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return index of the {@link Snapshot.Root} node in the inodes array,
|
* @return index of the {@link Snapshot.Root} node in the inodes array,
|
||||||
* -1 for non-snapshot paths.
|
* -1 for non-snapshot paths.
|
||||||
|
@ -398,7 +403,7 @@ public class INodesInPath {
|
||||||
|
|
||||||
private String toString(boolean vaildateObject) {
|
private String toString(boolean vaildateObject) {
|
||||||
if (vaildateObject) {
|
if (vaildateObject) {
|
||||||
vaildate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
final StringBuilder b = new StringBuilder(getClass().getSimpleName())
|
final StringBuilder b = new StringBuilder(getClass().getSimpleName())
|
||||||
|
@ -423,7 +428,7 @@ public class INodesInPath {
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vaildate() {
|
void validate() {
|
||||||
// check parent up to snapshotRootIndex or numNonNull
|
// check parent up to snapshotRootIndex or numNonNull
|
||||||
final int n = snapshotRootIndex >= 0? snapshotRootIndex + 1: numNonNull;
|
final int n = snapshotRootIndex >= 0? snapshotRootIndex + 1: numNonNull;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
|
@ -173,16 +173,15 @@ public class SnapshotManager implements SnapshotStatsMXBean {
|
||||||
* Find the source root directory where the snapshot will be taken
|
* Find the source root directory where the snapshot will be taken
|
||||||
* for a given path.
|
* for a given path.
|
||||||
*
|
*
|
||||||
* @param path The directory path where the snapshot will be taken.
|
|
||||||
* @return Snapshottable directory.
|
* @return Snapshottable directory.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* Throw IOException when the given path does not lead to an
|
* Throw IOException when the given path does not lead to an
|
||||||
* existing snapshottable directory.
|
* existing snapshottable directory.
|
||||||
*/
|
*/
|
||||||
public INodeDirectory getSnapshottableRoot(final String path)
|
public INodeDirectory getSnapshottableRoot(final INodesInPath iip)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final INodeDirectory dir = INodeDirectory.valueOf(fsdir
|
final String path = iip.getPath();
|
||||||
.getINodesInPath4Write(path).getLastINode(), path);
|
final INodeDirectory dir = INodeDirectory.valueOf(iip.getLastINode(), path);
|
||||||
if (!dir.isSnapshottable()) {
|
if (!dir.isSnapshottable()) {
|
||||||
throw new SnapshotException(
|
throw new SnapshotException(
|
||||||
"Directory is not a snapshottable directory: " + path);
|
"Directory is not a snapshottable directory: " + path);
|
||||||
|
@ -194,8 +193,7 @@ public class SnapshotManager implements SnapshotStatsMXBean {
|
||||||
* Create a snapshot of the given path.
|
* Create a snapshot of the given path.
|
||||||
* It is assumed that the caller will perform synchronization.
|
* It is assumed that the caller will perform synchronization.
|
||||||
*
|
*
|
||||||
* @param path
|
* @param iip the INodes resolved from the snapshottable directory's path
|
||||||
* The directory path where the snapshot will be taken.
|
|
||||||
* @param snapshotName
|
* @param snapshotName
|
||||||
* The name of the snapshot.
|
* The name of the snapshot.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
@ -204,9 +202,9 @@ public class SnapshotManager implements SnapshotStatsMXBean {
|
||||||
* snapshot with the given name for the directory, and/or 3)
|
* snapshot with the given name for the directory, and/or 3)
|
||||||
* snapshot number exceeds quota
|
* snapshot number exceeds quota
|
||||||
*/
|
*/
|
||||||
public String createSnapshot(final String path, String snapshotName
|
public String createSnapshot(final INodesInPath iip, String snapshotRoot,
|
||||||
) throws IOException {
|
String snapshotName) throws IOException {
|
||||||
INodeDirectory srcRoot = getSnapshottableRoot(path);
|
INodeDirectory srcRoot = getSnapshottableRoot(iip);
|
||||||
|
|
||||||
if (snapshotCounter == getMaxSnapshotID()) {
|
if (snapshotCounter == getMaxSnapshotID()) {
|
||||||
// We have reached the maximum allowable snapshot ID and since we don't
|
// We have reached the maximum allowable snapshot ID and since we don't
|
||||||
|
@ -223,31 +221,25 @@ public class SnapshotManager implements SnapshotStatsMXBean {
|
||||||
//create success, update id
|
//create success, update id
|
||||||
snapshotCounter++;
|
snapshotCounter++;
|
||||||
numSnapshots.getAndIncrement();
|
numSnapshots.getAndIncrement();
|
||||||
return Snapshot.getSnapshotPath(path, snapshotName);
|
return Snapshot.getSnapshotPath(snapshotRoot, snapshotName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a snapshot for a snapshottable directory
|
* Delete a snapshot for a snapshottable directory
|
||||||
* @param path Path to the directory where the snapshot was taken
|
|
||||||
* @param snapshotName Name of the snapshot to be deleted
|
* @param snapshotName Name of the snapshot to be deleted
|
||||||
* @param collectedBlocks Used to collect information to update blocksMap
|
* @param collectedBlocks Used to collect information to update blocksMap
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void deleteSnapshot(final String path, final String snapshotName,
|
public void deleteSnapshot(final INodesInPath iip, final String snapshotName,
|
||||||
BlocksMapUpdateInfo collectedBlocks, final List<INode> removedINodes)
|
BlocksMapUpdateInfo collectedBlocks, final List<INode> removedINodes)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// parse the path, and check if the path is a snapshot path
|
INodeDirectory srcRoot = getSnapshottableRoot(iip);
|
||||||
// the INodeDirectorySnapshottable#valueOf method will throw Exception
|
|
||||||
// if the path is not for a snapshottable directory
|
|
||||||
INodeDirectory srcRoot = getSnapshottableRoot(path);
|
|
||||||
srcRoot.removeSnapshot(snapshotName, collectedBlocks, removedINodes);
|
srcRoot.removeSnapshot(snapshotName, collectedBlocks, removedINodes);
|
||||||
numSnapshots.getAndDecrement();
|
numSnapshots.getAndDecrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename the given snapshot
|
* Rename the given snapshot
|
||||||
* @param path
|
|
||||||
* The directory path where the snapshot was taken
|
|
||||||
* @param oldSnapshotName
|
* @param oldSnapshotName
|
||||||
* Old name of the snapshot
|
* Old name of the snapshot
|
||||||
* @param newSnapshotName
|
* @param newSnapshotName
|
||||||
|
@ -258,14 +250,11 @@ public class SnapshotManager implements SnapshotStatsMXBean {
|
||||||
* old name does not exist for the directory, and/or 3) there exists
|
* old name does not exist for the directory, and/or 3) there exists
|
||||||
* a snapshot with the new name for the directory
|
* a snapshot with the new name for the directory
|
||||||
*/
|
*/
|
||||||
public void renameSnapshot(final String path, final String oldSnapshotName,
|
public void renameSnapshot(final INodesInPath iip, final String snapshotRoot,
|
||||||
final String newSnapshotName) throws IOException {
|
final String oldSnapshotName, final String newSnapshotName)
|
||||||
// Find the source root directory path where the snapshot was taken.
|
throws IOException {
|
||||||
// All the check for path has been included in the valueOf method.
|
final INodeDirectory srcRoot = getSnapshottableRoot(iip);
|
||||||
final INodeDirectory srcRoot = getSnapshottableRoot(path);
|
srcRoot.renameSnapshot(snapshotRoot, oldSnapshotName, newSnapshotName);
|
||||||
// Note that renameSnapshot and createSnapshot are synchronized externally
|
|
||||||
// through FSNamesystem's write lock
|
|
||||||
srcRoot.renameSnapshot(path, oldSnapshotName, newSnapshotName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumSnapshottableDirs() {
|
public int getNumSnapshottableDirs() {
|
||||||
|
@ -366,22 +355,23 @@ public class SnapshotManager implements SnapshotStatsMXBean {
|
||||||
* Compute the difference between two snapshots of a directory, or between a
|
* Compute the difference between two snapshots of a directory, or between a
|
||||||
* snapshot of the directory and its current tree.
|
* snapshot of the directory and its current tree.
|
||||||
*/
|
*/
|
||||||
public SnapshotDiffReport diff(final String path, final String from,
|
public SnapshotDiffReport diff(final INodesInPath iip,
|
||||||
|
final String snapshotRootPath, final String from,
|
||||||
final String to) throws IOException {
|
final String to) throws IOException {
|
||||||
// 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.
|
||||||
final INodeDirectory snapshotRoot = getSnapshottableRoot(path);
|
final INodeDirectory snapshotRoot = getSnapshottableRoot(iip);
|
||||||
|
|
||||||
if ((from == null || from.isEmpty())
|
if ((from == null || from.isEmpty())
|
||||||
&& (to == null || to.isEmpty())) {
|
&& (to == null || to.isEmpty())) {
|
||||||
// both fromSnapshot and toSnapshot indicate the current tree
|
// both fromSnapshot and toSnapshot indicate the current tree
|
||||||
return new SnapshotDiffReport(path, from, to,
|
return new SnapshotDiffReport(snapshotRootPath, from, to,
|
||||||
Collections.<DiffReportEntry> emptyList());
|
Collections.<DiffReportEntry> emptyList());
|
||||||
}
|
}
|
||||||
final SnapshotDiffInfo diffs = snapshotRoot
|
final SnapshotDiffInfo diffs = snapshotRoot
|
||||||
.getDirectorySnapshottableFeature().computeDiff(snapshotRoot, from, to);
|
.getDirectorySnapshottableFeature().computeDiff(snapshotRoot, from, to);
|
||||||
return diffs != null ? diffs.generateReport() : new SnapshotDiffReport(
|
return diffs != null ? diffs.generateReport() : new SnapshotDiffReport(
|
||||||
path, from, to, Collections.<DiffReportEntry> emptyList());
|
snapshotRootPath, from, to, Collections.<DiffReportEntry> emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearSnapshottableDirs() {
|
public void clearSnapshottableDirs() {
|
||||||
|
|
|
@ -402,15 +402,17 @@ public class TestFSPermissionChecker {
|
||||||
|
|
||||||
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,
|
INodesInPath iip = dir.getINodesInPath(path, true);
|
||||||
dir, false, null, null, access, null, false, true);
|
new FSPermissionChecker(SUPERUSER, SUPERGROUP, user).checkPermission(iip,
|
||||||
|
false, null, null, access, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
INodesInPath iip = dir.getINodesInPath(path, true);
|
||||||
dir, false, null, null, access, null, false, true);
|
new FSPermissionChecker(SUPERUSER, SUPERGROUP, user).checkPermission(iip,
|
||||||
|
false, null, null, access, null, false);
|
||||||
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) {
|
||||||
|
|
|
@ -48,22 +48,20 @@ public class TestSnapshotPathINodes {
|
||||||
static private final Path file1 = new Path(sub1, "file1");
|
static private final Path file1 = new Path(sub1, "file1");
|
||||||
static private final Path file2 = new Path(sub1, "file2");
|
static private final Path file2 = new Path(sub1, "file2");
|
||||||
|
|
||||||
static private Configuration conf;
|
|
||||||
static private MiniDFSCluster cluster;
|
static private MiniDFSCluster cluster;
|
||||||
static private FSNamesystem fsn;
|
|
||||||
static private FSDirectory fsdir;
|
static private FSDirectory fsdir;
|
||||||
|
|
||||||
static private DistributedFileSystem hdfs;
|
static private DistributedFileSystem hdfs;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() throws Exception {
|
public static void setUp() throws Exception {
|
||||||
conf = new Configuration();
|
Configuration conf = new Configuration();
|
||||||
cluster = new MiniDFSCluster.Builder(conf)
|
cluster = new MiniDFSCluster.Builder(conf)
|
||||||
.numDataNodes(REPLICATION)
|
.numDataNodes(REPLICATION)
|
||||||
.build();
|
.build();
|
||||||
cluster.waitActive();
|
cluster.waitActive();
|
||||||
|
|
||||||
fsn = cluster.getNamesystem();
|
FSNamesystem fsn = cluster.getNamesystem();
|
||||||
fsdir = fsn.getFSDirectory();
|
fsdir = fsn.getFSDirectory();
|
||||||
|
|
||||||
hdfs = cluster.getFileSystem();
|
hdfs = cluster.getFileSystem();
|
||||||
|
@ -136,7 +134,6 @@ public class TestSnapshotPathINodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test {@link INodeDirectory#getExistingPathINodes(byte[][], int, boolean)}
|
|
||||||
* for normal (non-snapshot) file.
|
* for normal (non-snapshot) file.
|
||||||
*/
|
*/
|
||||||
@Test (timeout=15000)
|
@Test (timeout=15000)
|
||||||
|
@ -180,7 +177,6 @@ public class TestSnapshotPathINodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test {@link INodeDirectory#getExistingPathINodes(byte[][], int, boolean)}
|
|
||||||
* for snapshot file.
|
* for snapshot file.
|
||||||
*/
|
*/
|
||||||
@Test (timeout=15000)
|
@Test (timeout=15000)
|
||||||
|
@ -259,7 +255,6 @@ public class TestSnapshotPathINodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test {@link INodeDirectory#getExistingPathINodes(byte[][], int, boolean)}
|
|
||||||
* for snapshot file after deleting the original file.
|
* for snapshot file after deleting the original file.
|
||||||
*/
|
*/
|
||||||
@Test (timeout=15000)
|
@Test (timeout=15000)
|
||||||
|
@ -317,10 +312,7 @@ public class TestSnapshotPathINodes {
|
||||||
hdfs.disallowSnapshot(sub1);
|
hdfs.disallowSnapshot(sub1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static private Snapshot s4;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test {@link INodeDirectory#getExistingPathINodes(byte[][], int, boolean)}
|
|
||||||
* for snapshot file while adding a new file after snapshot.
|
* for snapshot file while adding a new file after snapshot.
|
||||||
*/
|
*/
|
||||||
@Test (timeout=15000)
|
@Test (timeout=15000)
|
||||||
|
@ -334,6 +326,7 @@ public class TestSnapshotPathINodes {
|
||||||
final Path file3 = new Path(sub1, "file3");
|
final Path file3 = new Path(sub1, "file3");
|
||||||
DFSTestUtil.createFile(hdfs, file3, 1024, REPLICATION, seed);
|
DFSTestUtil.createFile(hdfs, file3, 1024, REPLICATION, seed);
|
||||||
|
|
||||||
|
Snapshot s4;
|
||||||
{
|
{
|
||||||
// Check the inodes for /TestSnapshot/sub1/.snapshot/s4/file3
|
// Check the inodes for /TestSnapshot/sub1/.snapshot/s4/file3
|
||||||
String snapshotPath = sub1.toString() + "/.snapshot/s4/file3";
|
String snapshotPath = sub1.toString() + "/.snapshot/s4/file3";
|
||||||
|
@ -379,7 +372,6 @@ public class TestSnapshotPathINodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test {@link INodeDirectory#getExistingPathINodes(byte[][], int, boolean)}
|
|
||||||
* for snapshot file while modifying file after snapshot.
|
* for snapshot file while modifying file after snapshot.
|
||||||
*/
|
*/
|
||||||
@Test (timeout=15000)
|
@Test (timeout=15000)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
package org.apache.hadoop.hdfs.server.namenode.snapshot;
|
package org.apache.hadoop.hdfs.server.namenode.snapshot;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.anyObject;
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
@ -29,6 +30,7 @@ import org.apache.hadoop.hdfs.protocol.SnapshotException;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.FSDirectory;
|
import org.apache.hadoop.hdfs.server.namenode.FSDirectory;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.INode;
|
import org.apache.hadoop.hdfs.server.namenode.INode;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.INodeDirectory;
|
import org.apache.hadoop.hdfs.server.namenode.INodeDirectory;
|
||||||
|
import org.apache.hadoop.hdfs.server.namenode.INodesInPath;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -48,22 +50,23 @@ public class TestSnapshotManager {
|
||||||
//
|
//
|
||||||
INodeDirectory ids = mock(INodeDirectory.class);
|
INodeDirectory ids = mock(INodeDirectory.class);
|
||||||
FSDirectory fsdir = mock(FSDirectory.class);
|
FSDirectory fsdir = mock(FSDirectory.class);
|
||||||
|
INodesInPath iip = mock(INodesInPath.class);
|
||||||
|
|
||||||
SnapshotManager sm = spy(new SnapshotManager(fsdir));
|
SnapshotManager sm = spy(new SnapshotManager(fsdir));
|
||||||
doReturn(ids).when(sm).getSnapshottableRoot(anyString());
|
doReturn(ids).when(sm).getSnapshottableRoot((INodesInPath) anyObject());
|
||||||
doReturn(testMaxSnapshotLimit).when(sm).getMaxSnapshotID();
|
doReturn(testMaxSnapshotLimit).when(sm).getMaxSnapshotID();
|
||||||
|
|
||||||
// Create testMaxSnapshotLimit snapshots. These should all succeed.
|
// Create testMaxSnapshotLimit snapshots. These should all succeed.
|
||||||
//
|
//
|
||||||
for (Integer i = 0; i < testMaxSnapshotLimit; ++i) {
|
for (Integer i = 0; i < testMaxSnapshotLimit; ++i) {
|
||||||
sm.createSnapshot("dummy", i.toString());
|
sm.createSnapshot(iip, "dummy", i.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to create one more snapshot. This should fail due to snapshot
|
// Attempt to create one more snapshot. This should fail due to snapshot
|
||||||
// ID rollover.
|
// ID rollover.
|
||||||
//
|
//
|
||||||
try {
|
try {
|
||||||
sm.createSnapshot("dummy", "shouldFailSnapshot");
|
sm.createSnapshot(iip, "dummy", "shouldFailSnapshot");
|
||||||
Assert.fail("Expected SnapshotException not thrown");
|
Assert.fail("Expected SnapshotException not thrown");
|
||||||
} catch (SnapshotException se) {
|
} catch (SnapshotException se) {
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
|
@ -72,13 +75,14 @@ public class TestSnapshotManager {
|
||||||
|
|
||||||
// Delete a snapshot to free up a slot.
|
// Delete a snapshot to free up a slot.
|
||||||
//
|
//
|
||||||
sm.deleteSnapshot("", "", mock(INode.BlocksMapUpdateInfo.class), new ArrayList<INode>());
|
sm.deleteSnapshot(iip, "", mock(INode.BlocksMapUpdateInfo.class),
|
||||||
|
new ArrayList<INode>());
|
||||||
|
|
||||||
// Attempt to create a snapshot again. It should still fail due
|
// Attempt to create a snapshot again. It should still fail due
|
||||||
// to snapshot ID rollover.
|
// to snapshot ID rollover.
|
||||||
//
|
//
|
||||||
try {
|
try {
|
||||||
sm.createSnapshot("dummy", "shouldFailSnapshot2");
|
sm.createSnapshot(iip, "dummy", "shouldFailSnapshot2");
|
||||||
Assert.fail("Expected SnapshotException not thrown");
|
Assert.fail("Expected SnapshotException not thrown");
|
||||||
} catch (SnapshotException se) {
|
} catch (SnapshotException se) {
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
|
|
Loading…
Reference in New Issue