HDFS-10851. FSDirStatAndListingOp: stop passing path as string. Contributed by Daryn Sharp.

(cherry picked from commit 2551ff80b7)
This commit is contained in:
Kihwal Lee 2016-09-30 16:02:26 -05:00
parent 345debf22e
commit bfc7f0630b
8 changed files with 126 additions and 190 deletions

View File

@ -152,7 +152,6 @@ class FSDirAclOp {
fsd.readLock(); fsd.readLock();
try { try {
INodesInPath iip = fsd.resolvePath(pc, src); INodesInPath iip = fsd.resolvePath(pc, src);
src = iip.getPath();
// There is no real inode for the path ending in ".snapshot", so return a // There is no real inode for the path ending in ".snapshot", so return a
// non-null, unpopulated AclStatus. This is similar to getFileInfo. // non-null, unpopulated AclStatus. This is similar to getFileInfo.
if (iip.isDotSnapshotDir() && fsd.getINode4DotSnapshot(iip) != null) { if (iip.isDotSnapshotDir() && fsd.getINode4DotSnapshot(iip) != null) {
@ -163,8 +162,7 @@ class FSDirAclOp {
} }
INode inode = FSDirectory.resolveLastINode(iip); INode inode = FSDirectory.resolveLastINode(iip);
int snapshotId = iip.getPathSnapshotId(); int snapshotId = iip.getPathSnapshotId();
List<AclEntry> acl = AclStorage.readINodeAcl(fsd.getAttributes(src, List<AclEntry> acl = AclStorage.readINodeAcl(fsd.getAttributes(iip));
inode.getLocalNameBytes(), inode, snapshotId));
FsPermission fsPermission = inode.getFsPermission(snapshotId); FsPermission fsPermission = inode.getFsPermission(snapshotId);
return new AclStatus.Builder() return new AclStatus.Builder()
.owner(inode.getUserName()).group(inode.getGroupName()) .owner(inode.getUserName()).group(inode.getGroupName())

View File

@ -51,15 +51,12 @@ 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 {
String src = null;
final INodesInPath iip; final INodesInPath iip;
if (fsd.isPermissionEnabled()) { if (fsd.isPermissionEnabled()) {
FSPermissionChecker pc = fsd.getPermissionChecker(); FSPermissionChecker pc = fsd.getPermissionChecker();
iip = fsd.resolvePath(pc, srcArg); iip = fsd.resolvePath(pc, srcArg);
src = iip.getPath();
} else { } else {
src = FSDirectory.resolvePath(srcArg, fsd); String src = FSDirectory.resolvePath(srcArg, fsd);
iip = fsd.getINodesInPath(src, true); iip = fsd.getINodesInPath(src, true);
} }
@ -90,7 +87,7 @@ class FSDirStatAndListingOp {
} }
isSuperUser = pc.isSuperUser(); isSuperUser = pc.isSuperUser();
} }
return getListing(fsd, iip, src, startAfter, needLocation, isSuperUser); return getListing(fsd, iip, startAfter, needLocation, isSuperUser);
} }
/** /**
@ -159,7 +156,6 @@ class FSDirStatAndListingOp {
"Negative length is not supported. File: " + src); "Negative length is not supported. File: " + src);
CacheManager cm = fsd.getFSNamesystem().getCacheManager(); CacheManager cm = fsd.getFSNamesystem().getCacheManager();
BlockManager bm = fsd.getBlockManager(); BlockManager bm = fsd.getBlockManager();
boolean isReservedName = FSDirectory.isReservedRawName(src);
fsd.readLock(); fsd.readLock();
try { try {
final INodesInPath iip = fsd.resolvePath(pc, src); final INodesInPath iip = fsd.resolvePath(pc, src);
@ -182,7 +178,7 @@ class FSDirStatAndListingOp {
isUc = false; isUc = false;
} }
final FileEncryptionInfo feInfo = isReservedName ? null final FileEncryptionInfo feInfo = iip.isRaw() ? null
: FSDirEncryptionZoneOp.getFileEncryptionInfo(fsd, inode, : FSDirEncryptionZoneOp.getFileEncryptionInfo(fsd, inode,
iip.getPathSnapshotId(), iip); iip.getPathSnapshotId(), iip);
@ -221,42 +217,39 @@ class FSDirStatAndListingOp {
* @param fsd FSDirectory * @param fsd FSDirectory
* @param iip the INodesInPath instance containing all the INodes along the * @param iip the INodesInPath instance containing all the INodes along the
* path * path
* @param src the directory name
* @param startAfter the name to start listing after * @param startAfter the name to start listing after
* @param needLocation if block locations are returned * @param needLocation if block locations are returned
* @param includeStoragePolicy if storage policy is returned
* @return a partial listing starting after startAfter * @return a partial listing starting after startAfter
*/ */
private static DirectoryListing getListing(FSDirectory fsd, INodesInPath iip, private static DirectoryListing getListing(FSDirectory fsd, INodesInPath iip,
String src, byte[] startAfter, boolean needLocation, boolean isSuperUser) byte[] startAfter, boolean needLocation, boolean includeStoragePolicy)
throws IOException { throws IOException {
String srcs = FSDirectory.normalizePath(src); if (FSDirectory.isExactReservedName(iip.getPathComponents())) {
if (FSDirectory.isExactReservedName(srcs)) {
return getReservedListing(fsd); return getReservedListing(fsd);
} }
fsd.readLock(); fsd.readLock();
try { try {
if (srcs.endsWith(HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR)) { if (iip.isDotSnapshotDir()) {
return getSnapshotsListing(fsd, srcs, startAfter); return getSnapshotsListing(fsd, iip, startAfter);
} }
final int snapshot = iip.getPathSnapshotId(); final int snapshot = iip.getPathSnapshotId();
final INode targetNode = iip.getLastINode(); final INode targetNode = iip.getLastINode();
if (targetNode == null) if (targetNode == null) {
return null; return null;
byte parentStoragePolicy = isSuperUser ? }
targetNode.getStoragePolicyID() : HdfsConstants
.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED; byte parentStoragePolicy = includeStoragePolicy
? targetNode.getStoragePolicyID()
: HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
if (!targetNode.isDirectory()) { if (!targetNode.isDirectory()) {
// return the file's status. note that the iip already includes the // return the file's status. note that the iip already includes the
// target INode // target INode
INodeAttributes nodeAttrs = getINodeAttributes(
fsd, src, HdfsFileStatus.EMPTY_NAME, targetNode,
snapshot);
return new DirectoryListing( return new DirectoryListing(
new HdfsFileStatus[]{ createFileStatus( new HdfsFileStatus[]{ createFileStatus(
fsd, HdfsFileStatus.EMPTY_NAME, nodeAttrs, fsd, iip, null, parentStoragePolicy, needLocation)
needLocation, parentStoragePolicy, iip)
}, 0); }, 0);
} }
@ -270,20 +263,15 @@ class FSDirStatAndListingOp {
int listingCnt = 0; int listingCnt = 0;
HdfsFileStatus listing[] = new HdfsFileStatus[numOfListing]; HdfsFileStatus listing[] = new HdfsFileStatus[numOfListing];
for (int i = 0; i < numOfListing && locationBudget > 0; i++) { for (int i = 0; i < numOfListing && locationBudget > 0; i++) {
INode cur = contents.get(startChild+i); INode child = contents.get(startChild+i);
byte curPolicy = isSuperUser && !cur.isSymlink()? byte childStoragePolicy = (includeStoragePolicy && !child.isSymlink())
cur.getLocalStoragePolicyID(): ? getStoragePolicyID(child.getLocalStoragePolicyID(),
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED; parentStoragePolicy)
INodeAttributes nodeAttrs = getINodeAttributes( : parentStoragePolicy;
fsd, src, cur.getLocalNameBytes(), cur, listing[i] =
snapshot); createFileStatus(fsd, iip, child, childStoragePolicy, needLocation);
final INodesInPath iipWithChild = INodesInPath.append(iip, cur,
cur.getLocalNameBytes());
listing[i] = createFileStatus(fsd, cur.getLocalNameBytes(), nodeAttrs,
needLocation, getStoragePolicyID(curPolicy, parentStoragePolicy),
iipWithChild);
listingCnt++; listingCnt++;
if (needLocation) { if (listing[i] instanceof HdfsLocatedFileStatus) {
// Once we hit lsLimit locations, stop. // Once we hit lsLimit locations, stop.
// This helps to prevent excessively large response payloads. // This helps to prevent excessively large response payloads.
// Approximate #locations with locatedBlockCount() * repl_factor // Approximate #locations with locatedBlockCount() * repl_factor
@ -308,17 +296,16 @@ class FSDirStatAndListingOp {
* Get a listing of all the snapshots of a snapshottable directory * Get a listing of all the snapshots of a snapshottable directory
*/ */
private static DirectoryListing getSnapshotsListing( private static DirectoryListing getSnapshotsListing(
FSDirectory fsd, String src, byte[] startAfter) FSDirectory fsd, INodesInPath iip, byte[] startAfter)
throws IOException { throws IOException {
Preconditions.checkState(fsd.hasReadLock()); Preconditions.checkState(fsd.hasReadLock());
Preconditions.checkArgument( Preconditions.checkArgument(iip.isDotSnapshotDir(),
src.endsWith(HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR), "%s does not end with %s",
"%s does not end with %s", src, HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR); iip.getPath(), HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR);
// drop off the null .snapshot component
final String dirPath = FSDirectory.normalizePath(src.substring(0, iip = iip.getParentINodesInPath();
src.length() - HdfsConstants.DOT_SNAPSHOT_DIR.length())); final String dirPath = iip.getPath();
final INode node = iip.getLastINode();
final INode node = fsd.getINode(dirPath);
final INodeDirectory dirNode = INodeDirectory.valueOf(node, dirPath); final INodeDirectory dirNode = INodeDirectory.valueOf(node, dirPath);
final DirectorySnapshottableFeature sf = dirNode.getDirectorySnapshottableFeature(); final DirectorySnapshottableFeature sf = dirNode.getDirectorySnapshottableFeature();
if (sf == null) { if (sf == null) {
@ -332,13 +319,8 @@ class FSDirStatAndListingOp {
final HdfsFileStatus listing[] = new HdfsFileStatus[numOfListing]; final HdfsFileStatus listing[] = new HdfsFileStatus[numOfListing];
for (int i = 0; i < numOfListing; i++) { for (int i = 0; i < numOfListing; i++) {
Snapshot.Root sRoot = snapshots.get(i + skipSize).getRoot(); Snapshot.Root sRoot = snapshots.get(i + skipSize).getRoot();
INodeAttributes nodeAttrs = getINodeAttributes( listing[i] = createFileStatus(fsd, iip, sRoot,
fsd, src, sRoot.getLocalNameBytes(), HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED, false);
node, Snapshot.CURRENT_STATE_ID);
listing[i] = createFileStatus(
fsd, sRoot.getLocalNameBytes(), nodeAttrs,
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED,
INodesInPath.fromINode(sRoot));
} }
return new DirectoryListing( return new DirectoryListing(
listing, snapshots.size() - skipSize - numOfListing); listing, snapshots.size() - skipSize - numOfListing);
@ -356,7 +338,6 @@ class FSDirStatAndListingOp {
/** Get the file info for a specific file. /** Get the file info for a specific file.
* @param fsd FSDirectory * @param fsd FSDirectory
* @param iip The path to the file, the file is included * @param iip The path to the file, the file is included
* @param isRawPath true if a /.reserved/raw pathname was passed by the user
* @param includeStoragePolicy whether to include storage policy * @param includeStoragePolicy whether to include storage policy
* @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
@ -369,15 +350,10 @@ class FSDirStatAndListingOp {
if (node == null) { if (node == null) {
return null; return null;
} }
byte policy = (includeStoragePolicy && !node.isSymlink())
byte policyId = includeStoragePolicy && !node.isSymlink() ? ? node.getStoragePolicyID()
node.getStoragePolicyID() : : HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED; return createFileStatus(fsd, iip, null, policy, false);
INodeAttributes nodeAttrs = getINodeAttributes(fsd, iip.getPath(),
HdfsFileStatus.EMPTY_NAME,
node, iip.getPathSnapshotId());
return createFileStatus(fsd, HdfsFileStatus.EMPTY_NAME, nodeAttrs,
policyId, iip);
} finally { } finally {
fsd.readUnlock(); fsd.readUnlock();
} }
@ -404,48 +380,41 @@ class FSDirStatAndListingOp {
} }
/** /**
* create an hdfs file status from an inode * create a hdfs file status from an iip.
* @param fsd FSDirectory
* @param iip The INodesInPath containing the INodeFile and its ancestors
* @return HdfsFileStatus without locations or storage policy
*/
static HdfsFileStatus createFileStatusForEditLog(
FSDirectory fsd, INodesInPath iip) throws IOException {
return createFileStatus(fsd, iip,
null, HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED, false);
}
/**
* create a hdfs file status from an iip.
* *
* @param fsd FSDirectory * @param fsd FSDirectory
* @param path the local name * @param iip The INodesInPath containing the INodeFile and its ancestors.
* @param child for a directory listing of the iip, else null
* @param storagePolicy for the path or closest ancestor
* @param needLocation if block locations need to be included or not * @param needLocation if block locations need to be included or not
* @param isRawPath true if this is being called on behalf of a path in * @param includeStoragePolicy if storage policy should be returned
* /.reserved/raw
* @param iip the INodesInPath containing the target INode and its ancestors
* @return a file status * @return a file status
* @throws java.io.IOException if any error occurs * @throws java.io.IOException if any error occurs
*/ */
private static HdfsFileStatus createFileStatus( private static HdfsFileStatus createFileStatus(
FSDirectory fsd, byte[] path, INodeAttributes nodeAttrs, FSDirectory fsd, INodesInPath iip, INode child, byte storagePolicy,
boolean needLocation, byte storagePolicy, INodesInPath iip) boolean needLocation) throws IOException {
throws IOException { assert fsd.hasReadLock();
if (needLocation) { // only directory listing sets the status name.
return createLocatedFileStatus(fsd, path, nodeAttrs, storagePolicy, iip); byte[] name = HdfsFileStatus.EMPTY_NAME;
} else { if (child != null) {
return createFileStatus(fsd, path, nodeAttrs, storagePolicy, iip); name = child.getLocalNameBytes();
} // have to do this for EC and EZ lookups...
iip = INodesInPath.append(iip, child, name);
} }
/**
* Create FileStatus for an given INodeFile.
* @param iip The INodesInPath containing the INodeFile and its ancestors
*/
static HdfsFileStatus createFileStatusForEditLog(
FSDirectory fsd, String fullPath, byte[] path,
byte storagePolicy, int snapshot, boolean isRawPath,
INodesInPath iip) throws IOException {
INodeAttributes nodeAttrs = getINodeAttributes(
fsd, fullPath, path, iip.getLastINode(), snapshot);
return createFileStatus(fsd, path, nodeAttrs, storagePolicy, iip);
}
/**
* create file status for a given INode
* @param iip the INodesInPath containing the target INode and its ancestors
*/
static HdfsFileStatus createFileStatus(
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;
@ -453,6 +422,7 @@ class FSDirStatAndListingOp {
final INode node = iip.getLastINode(); final INode node = iip.getLastINode();
final int snapshot = iip.getPathSnapshotId(); final int snapshot = iip.getPathSnapshotId();
final boolean isRawPath = iip.isRaw(); final boolean isRawPath = iip.isRaw();
LocatedBlocks loc = null;
final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp
.getFileEncryptionInfo(fsd, node, snapshot, iip); .getFileEncryptionInfo(fsd, node, snapshot, iip);
@ -464,6 +434,18 @@ class FSDirStatAndListingOp {
blocksize = fileNode.getPreferredBlockSize(); blocksize = fileNode.getPreferredBlockSize();
isEncrypted = (feInfo != null) isEncrypted = (feInfo != null)
|| (isRawPath && FSDirEncryptionZoneOp.isInAnEZ(fsd, iip)); || (isRawPath && FSDirEncryptionZoneOp.isInAnEZ(fsd, iip));
if (needLocation) {
final boolean inSnapshot = snapshot != Snapshot.CURRENT_STATE_ID;
final boolean isUc = !inSnapshot && fileNode.isUnderConstruction();
final long fileSize = !inSnapshot && isUc
? fileNode.computeFileSizeNotIncludingLastUcBlock() : size;
loc = fsd.getBlockManager().createLocatedBlocks(
fileNode.getBlocks(snapshot), fileSize, isUc, 0L, size, false,
inSnapshot, feInfo);
if (loc == null) {
loc = new LocatedBlocks();
}
}
} else { } else {
isEncrypted = FSDirEncryptionZoneOp.isInAnEZ(fsd, iip); isEncrypted = FSDirEncryptionZoneOp.isInAnEZ(fsd, iip);
} }
@ -471,7 +453,8 @@ class FSDirStatAndListingOp {
int childrenNum = node.isDirectory() ? int childrenNum = node.isDirectory() ?
node.asDirectory().getChildrenNum(snapshot) : 0; node.asDirectory().getChildrenNum(snapshot) : 0;
return new HdfsFileStatus( INodeAttributes nodeAttrs = fsd.getAttributes(iip);
HdfsFileStatus status = createFileStatus(
size, size,
node.isDirectory(), node.isDirectory(),
replication, replication,
@ -482,70 +465,13 @@ class FSDirStatAndListingOp {
nodeAttrs.getUserName(), nodeAttrs.getUserName(),
nodeAttrs.getGroupName(), nodeAttrs.getGroupName(),
node.isSymlink() ? node.asSymlink().getSymlink() : null, node.isSymlink() ? node.asSymlink().getSymlink() : null,
path, name,
node.getId(), node.getId(),
childrenNum, childrenNum,
feInfo, feInfo,
storagePolicy); storagePolicy,
} loc);
private static INodeAttributes getINodeAttributes(
FSDirectory fsd, String fullPath, byte[] path, INode node, int snapshot) {
return fsd.getAttributes(fullPath, path, node, snapshot);
}
/**
* Create FileStatus with location info by file INode
* @param iip the INodesInPath containing the target INode and its ancestors
*/
private static HdfsFileStatus createLocatedFileStatus(
FSDirectory fsd, byte[] path, INodeAttributes nodeAttrs,
byte storagePolicy, INodesInPath iip) throws IOException {
assert fsd.hasReadLock();
long size = 0; // length is zero for directories
short replication = 0;
long blocksize = 0;
LocatedBlocks loc = null;
final boolean isEncrypted;
final INode node = iip.getLastINode();
final int snapshot = iip.getPathSnapshotId();
final boolean isRawPath = iip.isRaw();
final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp
.getFileEncryptionInfo(fsd, node, snapshot, iip);
if (node.isFile()) {
final INodeFile fileNode = node.asFile();
size = fileNode.computeFileSize(snapshot);
replication = fileNode.getFileReplication(snapshot);
blocksize = fileNode.getPreferredBlockSize();
final boolean inSnapshot = snapshot != Snapshot.CURRENT_STATE_ID;
final boolean isUc = !inSnapshot && fileNode.isUnderConstruction();
final long fileSize = !inSnapshot && isUc ?
fileNode.computeFileSizeNotIncludingLastUcBlock() : size;
loc = fsd.getBlockManager().createLocatedBlocks(
fileNode.getBlocks(snapshot), fileSize, isUc, 0L, size, false,
inSnapshot, feInfo);
if (loc == null) {
loc = new LocatedBlocks();
}
isEncrypted = (feInfo != null)
|| (isRawPath && FSDirEncryptionZoneOp.isInAnEZ(fsd, iip));
} else {
isEncrypted = FSDirEncryptionZoneOp.isInAnEZ(fsd, iip);
}
int childrenNum = node.isDirectory() ?
node.asDirectory().getChildrenNum(snapshot) : 0;
HdfsLocatedFileStatus status =
new HdfsLocatedFileStatus(size, node.isDirectory(), replication,
blocksize, node.getModificationTime(snapshot),
node.getAccessTime(snapshot),
getPermissionForFileStatus(nodeAttrs, isEncrypted),
nodeAttrs.getUserName(), nodeAttrs.getGroupName(),
node.isSymlink() ? node.asSymlink().getSymlink() : null, path,
node.getId(), loc, childrenNum, feInfo, storagePolicy);
// Set caching information for the located blocks. // Set caching information for the located blocks.
if (loc != null) { if (loc != null) {
CacheManager cacheManager = fsd.getFSNamesystem().getCacheManager(); CacheManager cacheManager = fsd.getFSNamesystem().getCacheManager();
@ -556,6 +482,23 @@ class FSDirStatAndListingOp {
return status; return status;
} }
private static HdfsFileStatus createFileStatus(long length, boolean isdir,
int replication, long blocksize, long mtime,
long atime, FsPermission permission, String owner, String group,
byte[] symlink, byte[] path, long fileId, int childrenNum,
FileEncryptionInfo feInfo, byte storagePolicy,
LocatedBlocks locations) {
if (locations == null) {
return new HdfsFileStatus(length, isdir, replication, blocksize,
mtime, atime, permission, owner, group, symlink, path, fileId,
childrenNum, feInfo, storagePolicy);
} else {
return new HdfsLocatedFileStatus(length, isdir, replication, blocksize,
mtime, atime, permission, owner, group, symlink, path, fileId,
locations, childrenNum, feInfo, storagePolicy);
}
}
/** /**
* Returns an inode's FsPermission for use in an outbound FileStatus. If the * Returns an inode's FsPermission for use in an outbound FileStatus. If the
* inode has an ACL or is for an encrypted file/dir, then this method will * inode has an ACL or is for an encrypted file/dir, then this method will

View File

@ -429,11 +429,7 @@ class FSDirXAttrOp {
throws IOException { throws IOException {
fsd.readLock(); fsd.readLock();
try { try {
String src = iip.getPath(); return XAttrStorage.readINodeXAttrs(fsd.getAttributes(iip));
INode inode = FSDirectory.resolveLastINode(iip);
int snapshotId = iip.getPathSnapshotId();
return XAttrStorage.readINodeXAttrs(fsd.getAttributes(src,
inode.getLocalNameBytes(), inode, snapshotId));
} finally { } finally {
fsd.readUnlock(); fsd.readUnlock();
} }

View File

@ -1683,14 +1683,19 @@ public class FSDirectory implements Closeable {
inodeId.setCurrentValue(newValue); inodeId.setCurrentValue(newValue);
} }
INodeAttributes getAttributes(String fullPath, byte[] path, INodeAttributes getAttributes(INodesInPath iip)
INode node, int snapshot) { throws FileNotFoundException {
INode node = FSDirectory.resolveLastINode(iip);
int snapshot = iip.getPathSnapshotId();
INodeAttributes nodeAttrs = node.getSnapshotINode(snapshot); INodeAttributes nodeAttrs = node.getSnapshotINode(snapshot);
if (attributeProvider != null) { if (attributeProvider != null) {
fullPath = fullPath // permission checking sends the full components array including the
+ (fullPath.endsWith(Path.SEPARATOR) ? "" : Path.SEPARATOR) // first empty component for the root. however file status
+ DFSUtil.bytes2String(path); // related calls are expected to strip out the root component according
nodeAttrs = attributeProvider.getAttributes(fullPath, nodeAttrs); // to TestINodeAttributeProvider.
byte[][] components = iip.getPathComponents();
components = Arrays.copyOfRange(components, 1, components.length);
nodeAttrs = attributeProvider.getAttributes(components, nodeAttrs);
} }
return nodeAttrs; return nodeAttrs;
} }

View File

@ -376,10 +376,8 @@ public class FSEditLogLoader {
// add the op into retry cache if necessary // add the op into retry cache if necessary
if (toAddRetryCache) { if (toAddRetryCache) {
HdfsFileStatus stat = FSDirStatAndListingOp.createFileStatusForEditLog( HdfsFileStatus stat =
fsNamesys.dir, path, HdfsFileStatus.EMPTY_NAME, FSDirStatAndListingOp.createFileStatusForEditLog(fsDir, iip);
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED, Snapshot.CURRENT_STATE_ID,
false, iip);
fsNamesys.addCacheEntryWithPayload(addCloseOp.rpcClientId, fsNamesys.addCacheEntryWithPayload(addCloseOp.rpcClientId,
addCloseOp.rpcCallId, stat); addCloseOp.rpcCallId, stat);
} }
@ -395,10 +393,8 @@ public class FSEditLogLoader {
false); false);
// add the op into retry cache if necessary // add the op into retry cache if necessary
if (toAddRetryCache) { if (toAddRetryCache) {
HdfsFileStatus stat = FSDirStatAndListingOp.createFileStatusForEditLog( HdfsFileStatus stat =
fsNamesys.dir, path, HdfsFileStatus.EMPTY_NAME, FSDirStatAndListingOp.createFileStatusForEditLog(fsDir, iip);
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED,
Snapshot.CURRENT_STATE_ID, false, iip);
fsNamesys.addCacheEntryWithPayload(addCloseOp.rpcClientId, fsNamesys.addCacheEntryWithPayload(addCloseOp.rpcClientId,
addCloseOp.rpcCallId, new LastBlockWithStatus(lb, stat)); addCloseOp.rpcCallId, new LastBlockWithStatus(lb, stat));
} }
@ -469,10 +465,8 @@ public class FSEditLogLoader {
false, false); false, false);
// add the op into retry cache if necessary // add the op into retry cache if necessary
if (toAddRetryCache) { if (toAddRetryCache) {
HdfsFileStatus stat = FSDirStatAndListingOp.createFileStatusForEditLog( HdfsFileStatus stat =
fsNamesys.dir, path, HdfsFileStatus.EMPTY_NAME, FSDirStatAndListingOp.createFileStatusForEditLog(fsDir, iip);
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED,
Snapshot.CURRENT_STATE_ID, false, iip);
fsNamesys.addCacheEntryWithPayload(appendOp.rpcClientId, fsNamesys.addCacheEntryWithPayload(appendOp.rpcClientId,
appendOp.rpcCallId, new LastBlockWithStatus(lb, stat)); appendOp.rpcCallId, new LastBlockWithStatus(lb, stat));
} }

View File

@ -17,13 +17,6 @@
*/ */
package org.apache.hadoop.hdfs.server.namenode; package org.apache.hadoop.hdfs.server.namenode;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.classification.InterfaceStability;
@ -87,7 +80,7 @@ public abstract class INodeAttributeProvider {
*/ */
public abstract void stop(); public abstract void stop();
@VisibleForTesting @Deprecated
String[] getPathElements(String path) { String[] getPathElements(String path) {
path = path.trim(); path = path.trim();
if (path.charAt(0) != Path.SEPARATOR_CHAR) { if (path.charAt(0) != Path.SEPARATOR_CHAR) {
@ -115,6 +108,7 @@ public abstract class INodeAttributeProvider {
return pathElements; return pathElements;
} }
@Deprecated
public INodeAttributes getAttributes(String fullPath, INodeAttributes inode) { public INodeAttributes getAttributes(String fullPath, INodeAttributes inode) {
return getAttributes(getPathElements(fullPath), inode); return getAttributes(getPathElements(fullPath), inode);
} }

View File

@ -399,7 +399,7 @@ public class INodesInPath {
*/ */
private INodesInPath getAncestorINodesInPath(int length) { private INodesInPath getAncestorINodesInPath(int length) {
Preconditions.checkArgument(length >= 0 && length < inodes.length); Preconditions.checkArgument(length >= 0 && length < inodes.length);
Preconditions.checkState(!isSnapshot()); Preconditions.checkState(isDotSnapshotDir() || !isSnapshot());
final INode[] anodes = new INode[length]; final INode[] anodes = new INode[length];
final byte[][] apath = new byte[length][]; final byte[][] apath = new byte[length][];
System.arraycopy(this.inodes, 0, anodes, 0, length); System.arraycopy(this.inodes, 0, anodes, 0, length);

View File

@ -166,6 +166,9 @@ public class TestSnapshotPathINodes {
assertEquals(sub1.toString(), nodesInPath.getPath(2)); assertEquals(sub1.toString(), nodesInPath.getPath(2));
assertEquals(file1.toString(), nodesInPath.getPath(3)); assertEquals(file1.toString(), nodesInPath.getPath(3));
assertEquals(file1.getParent().toString(),
nodesInPath.getParentINodesInPath().getPath());
nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false); nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false);
assertEquals(nodesInPath.length(), components.length); assertEquals(nodesInPath.length(), components.length);
assertSnapshot(nodesInPath, false, null, -1); assertSnapshot(nodesInPath, false, null, -1);
@ -212,6 +215,9 @@ public class TestSnapshotPathINodes {
// The number of INodes returned should still be components.length // The number of INodes returned should still be components.length
// since we put a null in the inode array for ".snapshot" // since we put a null in the inode array for ".snapshot"
assertEquals(nodesInPath.length(), components.length); assertEquals(nodesInPath.length(), components.length);
// ensure parent inodes can strip the .snapshot
assertEquals(sub1.toString(),
nodesInPath.getParentINodesInPath().getPath());
// No SnapshotRoot dir is included in the resolved inodes // No SnapshotRoot dir is included in the resolved inodes
assertSnapshot(nodesInPath, true, snapshot, -1); assertSnapshot(nodesInPath, true, snapshot, -1);