|
@@ -24,6 +24,7 @@ import org.apache.hadoop.fs.ContentSummary;
|
|
import org.apache.hadoop.fs.DirectoryListingStartAfterNotFoundException;
|
|
import org.apache.hadoop.fs.DirectoryListingStartAfterNotFoundException;
|
|
import org.apache.hadoop.fs.FileEncryptionInfo;
|
|
import org.apache.hadoop.fs.FileEncryptionInfo;
|
|
import org.apache.hadoop.fs.InvalidPathException;
|
|
import org.apache.hadoop.fs.InvalidPathException;
|
|
|
|
+import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.fs.permission.FsAction;
|
|
import org.apache.hadoop.fs.permission.FsAction;
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
import org.apache.hadoop.fs.QuotaUsage;
|
|
import org.apache.hadoop.fs.QuotaUsage;
|
|
@@ -52,7 +53,6 @@ import static org.apache.hadoop.util.Time.now;
|
|
class FSDirStatAndListingOp {
|
|
class FSDirStatAndListingOp {
|
|
static DirectoryListing getListingInt(FSDirectory fsd, final String srcArg,
|
|
static DirectoryListing getListingInt(FSDirectory fsd, final String srcArg,
|
|
byte[] startAfter, boolean needLocation) throws IOException {
|
|
byte[] startAfter, boolean needLocation) throws IOException {
|
|
- final String startAfterString = DFSUtil.bytes2String(startAfter);
|
|
|
|
String src = null;
|
|
String src = null;
|
|
|
|
|
|
final INodesInPath iip;
|
|
final INodesInPath iip;
|
|
@@ -65,16 +65,20 @@ class FSDirStatAndListingOp {
|
|
iip = fsd.getINodesInPath(src, true);
|
|
iip = fsd.getINodesInPath(src, true);
|
|
}
|
|
}
|
|
|
|
|
|
- // Get file name when startAfter is an INodePath
|
|
|
|
- if (FSDirectory.isReservedName(startAfterString)) {
|
|
|
|
- try {
|
|
|
|
- String tmp = FSDirectory.resolvePath(startAfterString, fsd);
|
|
|
|
- byte[][] regularPath = INode.getPathComponents(tmp);
|
|
|
|
- startAfter = regularPath[regularPath.length - 1];
|
|
|
|
- } catch (IOException e) {
|
|
|
|
- // Possibly the inode is deleted
|
|
|
|
- throw new DirectoryListingStartAfterNotFoundException(
|
|
|
|
- "Can't find startAfter " + startAfterString);
|
|
|
|
|
|
+ // Get file name when startAfter is an INodePath. This is not the
|
|
|
|
+ // common case so avoid any unnecessary processing unless required.
|
|
|
|
+ if (startAfter.length > 0 && startAfter[0] == Path.SEPARATOR_CHAR) {
|
|
|
|
+ final String startAfterString = DFSUtil.bytes2String(startAfter);
|
|
|
|
+ if (FSDirectory.isReservedName(startAfterString)) {
|
|
|
|
+ try {
|
|
|
|
+ byte[][] components = INode.getPathComponents(startAfterString);
|
|
|
|
+ components = FSDirectory.resolveComponents(components, fsd);
|
|
|
|
+ startAfter = components[components.length - 1];
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ // Possibly the inode is deleted
|
|
|
|
+ throw new DirectoryListingStartAfterNotFoundException(
|
|
|
|
+ "Can't find startAfter " + startAfterString);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -108,16 +112,16 @@ class FSDirStatAndListingOp {
|
|
if (!DFSUtil.isValidName(src)) {
|
|
if (!DFSUtil.isValidName(src)) {
|
|
throw new InvalidPathException("Invalid file name: " + src);
|
|
throw new InvalidPathException("Invalid file name: " + src);
|
|
}
|
|
}
|
|
|
|
+ final INodesInPath iip;
|
|
if (fsd.isPermissionEnabled()) {
|
|
if (fsd.isPermissionEnabled()) {
|
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
|
FSPermissionChecker pc = fsd.getPermissionChecker();
|
|
- final INodesInPath iip = fsd.resolvePath(pc, srcArg, resolveLink);
|
|
|
|
- src = iip.getPath();
|
|
|
|
|
|
+ iip = fsd.resolvePath(pc, srcArg, resolveLink);
|
|
fsd.checkPermission(pc, iip, false, null, null, null, null, false);
|
|
fsd.checkPermission(pc, iip, false, null, null, null, null, false);
|
|
} else {
|
|
} else {
|
|
src = FSDirectory.resolvePath(srcArg, fsd);
|
|
src = FSDirectory.resolvePath(srcArg, fsd);
|
|
|
|
+ iip = fsd.getINodesInPath(src, resolveLink);
|
|
}
|
|
}
|
|
- return getFileInfo(fsd, src, FSDirectory.isReservedRawName(srcArg),
|
|
|
|
- resolveLink);
|
|
|
|
|
|
+ return getFileInfo(fsd, iip);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -230,7 +234,6 @@ class FSDirStatAndListingOp {
|
|
String src, byte[] startAfter, boolean needLocation, boolean isSuperUser)
|
|
String src, byte[] startAfter, boolean needLocation, boolean isSuperUser)
|
|
throws IOException {
|
|
throws IOException {
|
|
String srcs = FSDirectory.normalizePath(src);
|
|
String srcs = FSDirectory.normalizePath(src);
|
|
- final boolean isRawPath = FSDirectory.isReservedRawName(src);
|
|
|
|
if (FSDirectory.isExactReservedName(srcs)) {
|
|
if (FSDirectory.isExactReservedName(srcs)) {
|
|
return getReservedListing(fsd);
|
|
return getReservedListing(fsd);
|
|
}
|
|
}
|
|
@@ -257,7 +260,7 @@ class FSDirStatAndListingOp {
|
|
return new DirectoryListing(
|
|
return new DirectoryListing(
|
|
new HdfsFileStatus[]{ createFileStatus(
|
|
new HdfsFileStatus[]{ createFileStatus(
|
|
fsd, HdfsFileStatus.EMPTY_NAME, nodeAttrs,
|
|
fsd, HdfsFileStatus.EMPTY_NAME, nodeAttrs,
|
|
- needLocation, parentStoragePolicy, snapshot, isRawPath, iip)
|
|
|
|
|
|
+ needLocation, parentStoragePolicy, iip)
|
|
}, 0);
|
|
}, 0);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -282,7 +285,7 @@ class FSDirStatAndListingOp {
|
|
cur.getLocalNameBytes());
|
|
cur.getLocalNameBytes());
|
|
listing[i] = createFileStatus(fsd, cur.getLocalNameBytes(), nodeAttrs,
|
|
listing[i] = createFileStatus(fsd, cur.getLocalNameBytes(), nodeAttrs,
|
|
needLocation, getStoragePolicyID(curPolicy, parentStoragePolicy),
|
|
needLocation, getStoragePolicyID(curPolicy, parentStoragePolicy),
|
|
- snapshot, isRawPath, iipWithChild);
|
|
|
|
|
|
+ iipWithChild);
|
|
listingCnt++;
|
|
listingCnt++;
|
|
if (needLocation) {
|
|
if (needLocation) {
|
|
// Once we hit lsLimit locations, stop.
|
|
// Once we hit lsLimit locations, stop.
|
|
@@ -339,7 +342,6 @@ class FSDirStatAndListingOp {
|
|
listing[i] = createFileStatus(
|
|
listing[i] = createFileStatus(
|
|
fsd, sRoot.getLocalNameBytes(), nodeAttrs,
|
|
fsd, sRoot.getLocalNameBytes(), nodeAttrs,
|
|
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED,
|
|
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED,
|
|
- Snapshot.CURRENT_STATE_ID, false,
|
|
|
|
INodesInPath.fromINode(sRoot));
|
|
INodesInPath.fromINode(sRoot));
|
|
}
|
|
}
|
|
return new DirectoryListing(
|
|
return new DirectoryListing(
|
|
@@ -363,10 +365,8 @@ class FSDirStatAndListingOp {
|
|
* @return object containing information regarding the file
|
|
* @return object containing information regarding the file
|
|
* or null if file not found
|
|
* or null if file not found
|
|
*/
|
|
*/
|
|
- static HdfsFileStatus getFileInfo(
|
|
|
|
- FSDirectory fsd, String path, INodesInPath iip, boolean isRawPath,
|
|
|
|
- boolean includeStoragePolicy)
|
|
|
|
- throws IOException {
|
|
|
|
|
|
+ static HdfsFileStatus getFileInfo(FSDirectory fsd,
|
|
|
|
+ INodesInPath iip, boolean includeStoragePolicy) throws IOException {
|
|
fsd.readLock();
|
|
fsd.readLock();
|
|
try {
|
|
try {
|
|
final INode node = iip.getLastINode();
|
|
final INode node = iip.getLastINode();
|
|
@@ -377,23 +377,21 @@ class FSDirStatAndListingOp {
|
|
byte policyId = includeStoragePolicy && !node.isSymlink() ?
|
|
byte policyId = includeStoragePolicy && !node.isSymlink() ?
|
|
node.getStoragePolicyID() :
|
|
node.getStoragePolicyID() :
|
|
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
|
|
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
|
|
- INodeAttributes nodeAttrs = getINodeAttributes(fsd, path,
|
|
|
|
|
|
+ INodeAttributes nodeAttrs = getINodeAttributes(fsd, iip.getPath(),
|
|
HdfsFileStatus.EMPTY_NAME,
|
|
HdfsFileStatus.EMPTY_NAME,
|
|
node, iip.getPathSnapshotId());
|
|
node, iip.getPathSnapshotId());
|
|
return createFileStatus(fsd, HdfsFileStatus.EMPTY_NAME, nodeAttrs,
|
|
return createFileStatus(fsd, HdfsFileStatus.EMPTY_NAME, nodeAttrs,
|
|
- policyId, iip.getPathSnapshotId(), isRawPath, iip);
|
|
|
|
|
|
+ policyId, iip);
|
|
} finally {
|
|
} finally {
|
|
fsd.readUnlock();
|
|
fsd.readUnlock();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- static HdfsFileStatus getFileInfo(
|
|
|
|
- FSDirectory fsd, String src, boolean resolveLink, boolean isRawPath)
|
|
|
|
|
|
+ static HdfsFileStatus getFileInfo(FSDirectory fsd, INodesInPath iip)
|
|
throws IOException {
|
|
throws IOException {
|
|
fsd.readLock();
|
|
fsd.readLock();
|
|
try {
|
|
try {
|
|
HdfsFileStatus status = null;
|
|
HdfsFileStatus status = null;
|
|
- final INodesInPath iip = fsd.getINodesInPath(src, resolveLink);
|
|
|
|
if (FSDirectory.isExactReservedName(iip.getPathComponents())) {
|
|
if (FSDirectory.isExactReservedName(iip.getPathComponents())) {
|
|
status = FSDirectory.DOT_RESERVED_STATUS;
|
|
status = FSDirectory.DOT_RESERVED_STATUS;
|
|
} else if (iip.isDotSnapshotDir()) {
|
|
} else if (iip.isDotSnapshotDir()) {
|
|
@@ -401,7 +399,7 @@ class FSDirStatAndListingOp {
|
|
status = FSDirectory.DOT_SNAPSHOT_DIR_STATUS;
|
|
status = FSDirectory.DOT_SNAPSHOT_DIR_STATUS;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- status = getFileInfo(fsd, src, iip, isRawPath, true);
|
|
|
|
|
|
+ status = getFileInfo(fsd, iip, true);
|
|
}
|
|
}
|
|
return status;
|
|
return status;
|
|
} finally {
|
|
} finally {
|
|
@@ -423,15 +421,12 @@ class FSDirStatAndListingOp {
|
|
*/
|
|
*/
|
|
private static HdfsFileStatus createFileStatus(
|
|
private static HdfsFileStatus createFileStatus(
|
|
FSDirectory fsd, byte[] path, INodeAttributes nodeAttrs,
|
|
FSDirectory fsd, byte[] path, INodeAttributes nodeAttrs,
|
|
- boolean needLocation, byte storagePolicy, int snapshot, boolean isRawPath,
|
|
|
|
- INodesInPath iip)
|
|
|
|
|
|
+ boolean needLocation, byte storagePolicy, INodesInPath iip)
|
|
throws IOException {
|
|
throws IOException {
|
|
if (needLocation) {
|
|
if (needLocation) {
|
|
- return createLocatedFileStatus(fsd, path, nodeAttrs, storagePolicy,
|
|
|
|
- snapshot, isRawPath, iip);
|
|
|
|
|
|
+ return createLocatedFileStatus(fsd, path, nodeAttrs, storagePolicy, iip);
|
|
} else {
|
|
} else {
|
|
- return createFileStatus(fsd, path, nodeAttrs, storagePolicy,
|
|
|
|
- snapshot, isRawPath, iip);
|
|
|
|
|
|
+ return createFileStatus(fsd, path, nodeAttrs, storagePolicy, iip);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -445,8 +440,7 @@ class FSDirStatAndListingOp {
|
|
INodesInPath iip) throws IOException {
|
|
INodesInPath iip) throws IOException {
|
|
INodeAttributes nodeAttrs = getINodeAttributes(
|
|
INodeAttributes nodeAttrs = getINodeAttributes(
|
|
fsd, fullPath, path, iip.getLastINode(), snapshot);
|
|
fsd, fullPath, path, iip.getLastINode(), snapshot);
|
|
- return createFileStatus(fsd, path, nodeAttrs, storagePolicy,
|
|
|
|
- snapshot, isRawPath, iip);
|
|
|
|
|
|
+ return createFileStatus(fsd, path, nodeAttrs, storagePolicy, iip);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -454,14 +448,15 @@ class FSDirStatAndListingOp {
|
|
* @param iip the INodesInPath containing the target INode and its ancestors
|
|
* @param iip the INodesInPath containing the target INode and its ancestors
|
|
*/
|
|
*/
|
|
static HdfsFileStatus createFileStatus(
|
|
static HdfsFileStatus createFileStatus(
|
|
- FSDirectory fsd, byte[] path,
|
|
|
|
- INodeAttributes nodeAttrs, byte storagePolicy, int snapshot,
|
|
|
|
- boolean isRawPath, INodesInPath iip) throws IOException {
|
|
|
|
|
|
+ FSDirectory fsd, byte[] path, INodeAttributes nodeAttrs,
|
|
|
|
+ byte storagePolicy, INodesInPath iip) throws IOException {
|
|
long size = 0; // length is zero for directories
|
|
long size = 0; // length is zero for directories
|
|
short replication = 0;
|
|
short replication = 0;
|
|
long blocksize = 0;
|
|
long blocksize = 0;
|
|
final boolean isEncrypted;
|
|
final boolean isEncrypted;
|
|
final INode node = iip.getLastINode();
|
|
final INode node = iip.getLastINode();
|
|
|
|
+ final int snapshot = iip.getPathSnapshotId();
|
|
|
|
+ final boolean isRawPath = iip.isRaw();
|
|
|
|
|
|
final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp
|
|
final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp
|
|
.getFileEncryptionInfo(fsd, node, snapshot, iip);
|
|
.getFileEncryptionInfo(fsd, node, snapshot, iip);
|
|
@@ -511,10 +506,9 @@ class FSDirStatAndListingOp {
|
|
* Create FileStatus with location info by file INode
|
|
* Create FileStatus with location info by file INode
|
|
* @param iip the INodesInPath containing the target INode and its ancestors
|
|
* @param iip the INodesInPath containing the target INode and its ancestors
|
|
*/
|
|
*/
|
|
- private static HdfsLocatedFileStatus createLocatedFileStatus(
|
|
|
|
|
|
+ private static HdfsFileStatus createLocatedFileStatus(
|
|
FSDirectory fsd, byte[] path, INodeAttributes nodeAttrs,
|
|
FSDirectory fsd, byte[] path, INodeAttributes nodeAttrs,
|
|
- byte storagePolicy, int snapshot,
|
|
|
|
- boolean isRawPath, INodesInPath iip) throws IOException {
|
|
|
|
|
|
+ byte storagePolicy, INodesInPath iip) throws IOException {
|
|
assert fsd.hasReadLock();
|
|
assert fsd.hasReadLock();
|
|
long size = 0; // length is zero for directories
|
|
long size = 0; // length is zero for directories
|
|
short replication = 0;
|
|
short replication = 0;
|
|
@@ -522,6 +516,8 @@ class FSDirStatAndListingOp {
|
|
LocatedBlocks loc = null;
|
|
LocatedBlocks loc = null;
|
|
final boolean isEncrypted;
|
|
final boolean isEncrypted;
|
|
final INode node = iip.getLastINode();
|
|
final INode node = iip.getLastINode();
|
|
|
|
+ final int snapshot = iip.getPathSnapshotId();
|
|
|
|
+ final boolean isRawPath = iip.isRaw();
|
|
|
|
|
|
final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp
|
|
final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp
|
|
.getFileEncryptionInfo(fsd, node, snapshot, iip);
|
|
.getFileEncryptionInfo(fsd, node, snapshot, iip);
|