HDFS-9621. Consolidate FSDirStatAndListingOp#createFileStatus to let its INodesInPath parameter always include the target INode. Contributed by Jing Zhao.

This commit is contained in:
Jing Zhao 2016-01-11 22:48:36 -08:00
parent 93b7ef8aec
commit 313f03bfda
5 changed files with 53 additions and 45 deletions

View File

@ -43,6 +43,9 @@ Release 2.9.0 - UNRELEASED
BUG FIXES BUG FIXES
HDFS-9621. Consolidate FSDirStatAndListingOp#createFileStatus to let its
INodesInPath parameter always include the target INode. (jing9)
Release 2.8.0 - UNRELEASED Release 2.8.0 - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -253,12 +253,14 @@ class FSDirStatAndListingOp {
.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED; .BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
if (!targetNode.isDirectory()) { if (!targetNode.isDirectory()) {
// return the file's status. note that the iip already includes the
// target INode
INodeAttributes nodeAttrs = getINodeAttributes( INodeAttributes nodeAttrs = getINodeAttributes(
fsd, src, HdfsFileStatus.EMPTY_NAME, targetNode, fsd, src, HdfsFileStatus.EMPTY_NAME, targetNode,
snapshot); snapshot);
return new DirectoryListing( return new DirectoryListing(
new HdfsFileStatus[]{ createFileStatus( new HdfsFileStatus[]{ createFileStatus(
fsd, HdfsFileStatus.EMPTY_NAME, targetNode, nodeAttrs, fsd, HdfsFileStatus.EMPTY_NAME, nodeAttrs,
needLocation, parentStoragePolicy, snapshot, isRawPath, iip) needLocation, parentStoragePolicy, snapshot, isRawPath, iip)
}, 0); }, 0);
} }
@ -272,7 +274,7 @@ class FSDirStatAndListingOp {
int locationBudget = fsd.getLsLimit(); int locationBudget = fsd.getLsLimit();
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 cur = contents.get(startChild+i);
byte curPolicy = isSuperUser && !cur.isSymlink()? byte curPolicy = isSuperUser && !cur.isSymlink()?
cur.getLocalStoragePolicyID(): cur.getLocalStoragePolicyID():
@ -280,9 +282,11 @@ class FSDirStatAndListingOp {
INodeAttributes nodeAttrs = getINodeAttributes( INodeAttributes nodeAttrs = getINodeAttributes(
fsd, src, cur.getLocalNameBytes(), cur, fsd, src, cur.getLocalNameBytes(), cur,
snapshot); snapshot);
listing[i] = createFileStatus(fsd, cur.getLocalNameBytes(), final INodesInPath iipWithChild = INodesInPath.append(iip, cur,
cur, nodeAttrs, needLocation, getStoragePolicyID(curPolicy, cur.getLocalNameBytes());
parentStoragePolicy), snapshot, isRawPath, iip); listing[i] = createFileStatus(fsd, cur.getLocalNameBytes(), nodeAttrs,
needLocation, getStoragePolicyID(curPolicy, parentStoragePolicy),
snapshot, isRawPath, iipWithChild);
listingCnt++; listingCnt++;
if (needLocation) { if (needLocation) {
// Once we hit lsLimit locations, stop. // Once we hit lsLimit locations, stop.
@ -337,8 +341,7 @@ class FSDirStatAndListingOp {
fsd, src, sRoot.getLocalNameBytes(), fsd, src, sRoot.getLocalNameBytes(),
node, Snapshot.CURRENT_STATE_ID); node, Snapshot.CURRENT_STATE_ID);
listing[i] = createFileStatus( listing[i] = createFileStatus(
fsd, sRoot.getLocalNameBytes(), fsd, sRoot.getLocalNameBytes(), nodeAttrs,
sRoot, nodeAttrs,
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED, HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED,
Snapshot.CURRENT_STATE_ID, false, Snapshot.CURRENT_STATE_ID, false,
INodesInPath.fromINode(sRoot)); INodesInPath.fromINode(sRoot));
@ -358,31 +361,31 @@ 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 src The string representation of the path to the file * @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 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
*/ */
static HdfsFileStatus getFileInfo( static HdfsFileStatus getFileInfo(
FSDirectory fsd, String path, INodesInPath src, boolean isRawPath, FSDirectory fsd, String path, INodesInPath iip, boolean isRawPath,
boolean includeStoragePolicy) boolean includeStoragePolicy)
throws IOException { throws IOException {
fsd.readLock(); fsd.readLock();
try { try {
final INode i = src.getLastINode(); final INode node = iip.getLastINode();
if (i == null) { if (node == null) {
return null; return null;
} }
byte policyId = includeStoragePolicy && !i.isSymlink() ? byte policyId = includeStoragePolicy && !node.isSymlink() ?
i.getStoragePolicyID() : node.getStoragePolicyID() :
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED; HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
INodeAttributes nodeAttrs = getINodeAttributes(fsd, path, INodeAttributes nodeAttrs = getINodeAttributes(fsd, path,
HdfsFileStatus.EMPTY_NAME, HdfsFileStatus.EMPTY_NAME,
i, src.getPathSnapshotId()); node, iip.getPathSnapshotId());
return createFileStatus(fsd, HdfsFileStatus.EMPTY_NAME, i, nodeAttrs, return createFileStatus(fsd, HdfsFileStatus.EMPTY_NAME, nodeAttrs,
policyId, src.getPathSnapshotId(), isRawPath, src); policyId, iip.getPathSnapshotId(), isRawPath, iip);
} finally { } finally {
fsd.readUnlock(); fsd.readUnlock();
} }
@ -419,51 +422,54 @@ class FSDirStatAndListingOp {
* *
* @param fsd FSDirectory * @param fsd FSDirectory
* @param path the local name * @param path the local name
* @param node inode
* @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 isRawPath true if this is being called on behalf of a path in
* /.reserved/raw * /.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, INode node, INodeAttributes nodeAttrs, FSDirectory fsd, byte[] path, INodeAttributes nodeAttrs,
boolean needLocation, byte storagePolicy, int snapshot, boolean isRawPath, boolean needLocation, byte storagePolicy, int snapshot, boolean isRawPath,
INodesInPath iip) INodesInPath iip)
throws IOException { throws IOException {
if (needLocation) { if (needLocation) {
return createLocatedFileStatus(fsd, path, node, nodeAttrs, storagePolicy, return createLocatedFileStatus(fsd, path, nodeAttrs, storagePolicy,
snapshot, isRawPath, iip); snapshot, isRawPath, iip);
} else { } else {
return createFileStatus(fsd, path, node, nodeAttrs, storagePolicy, return createFileStatus(fsd, path, nodeAttrs, storagePolicy,
snapshot, isRawPath, iip); snapshot, isRawPath, iip);
} }
} }
/** /**
* Create FileStatus by file INode * Create FileStatus for an given INodeFile.
* @param iip The INodesInPath containing the INodeFile and its ancestors
*/ */
static HdfsFileStatus createFileStatusForEditLog( static HdfsFileStatus createFileStatusForEditLog(
FSDirectory fsd, String fullPath, byte[] path, INode node, FSDirectory fsd, String fullPath, byte[] path,
byte storagePolicy, int snapshot, boolean isRawPath, byte storagePolicy, int snapshot, boolean isRawPath,
INodesInPath iip) throws IOException { INodesInPath iip) throws IOException {
INodeAttributes nodeAttrs = getINodeAttributes( INodeAttributes nodeAttrs = getINodeAttributes(
fsd, fullPath, path, node, snapshot); fsd, fullPath, path, iip.getLastINode(), snapshot);
return createFileStatus(fsd, path, node, nodeAttrs, return createFileStatus(fsd, path, nodeAttrs, storagePolicy,
storagePolicy, snapshot, isRawPath, iip); snapshot, isRawPath, iip);
} }
/** /**
* Create FileStatus by file INode * create file status for a given INode
* @param iip the INodesInPath containing the target INode and its ancestors
*/ */
static HdfsFileStatus createFileStatus( static HdfsFileStatus createFileStatus(
FSDirectory fsd, byte[] path, INode node, FSDirectory fsd, byte[] path,
INodeAttributes nodeAttrs, byte storagePolicy, int snapshot, INodeAttributes nodeAttrs, byte storagePolicy, int snapshot,
boolean isRawPath, INodesInPath iip) throws IOException { boolean isRawPath, 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 FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp
.getFileEncryptionInfo(fsd, node, snapshot, iip); .getFileEncryptionInfo(fsd, node, snapshot, iip);
@ -474,11 +480,9 @@ class FSDirStatAndListingOp {
replication = fileNode.getFileReplication(snapshot); replication = fileNode.getFileReplication(snapshot);
blocksize = fileNode.getPreferredBlockSize(); blocksize = fileNode.getPreferredBlockSize();
isEncrypted = (feInfo != null) isEncrypted = (feInfo != null)
|| (isRawPath && FSDirEncryptionZoneOp.isInAnEZ(fsd, || (isRawPath && FSDirEncryptionZoneOp.isInAnEZ(fsd, iip));
INodesInPath.fromINode(node)));
} else { } else {
isEncrypted = FSDirEncryptionZoneOp.isInAnEZ(fsd, isEncrypted = FSDirEncryptionZoneOp.isInAnEZ(fsd, iip);
INodesInPath.fromINode(node));
} }
int childrenNum = node.isDirectory() ? int childrenNum = node.isDirectory() ?
@ -509,9 +513,10 @@ 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
*/ */
private static HdfsLocatedFileStatus createLocatedFileStatus( private static HdfsLocatedFileStatus createLocatedFileStatus(
FSDirectory fsd, byte[] path, INode node, INodeAttributes nodeAttrs, FSDirectory fsd, byte[] path, INodeAttributes nodeAttrs,
byte storagePolicy, int snapshot, byte storagePolicy, int snapshot,
boolean isRawPath, INodesInPath iip) throws IOException { boolean isRawPath, INodesInPath iip) throws IOException {
assert fsd.hasReadLock(); assert fsd.hasReadLock();
@ -520,6 +525,8 @@ class FSDirStatAndListingOp {
long blocksize = 0; long blocksize = 0;
LocatedBlocks loc = null; LocatedBlocks loc = null;
final boolean isEncrypted; final boolean isEncrypted;
final INode node = iip.getLastINode();
final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp final FileEncryptionInfo feInfo = isRawPath ? null : FSDirEncryptionZoneOp
.getFileEncryptionInfo(fsd, node, snapshot, iip); .getFileEncryptionInfo(fsd, node, snapshot, iip);
if (node.isFile()) { if (node.isFile()) {
@ -540,11 +547,9 @@ class FSDirStatAndListingOp {
loc = new LocatedBlocks(); loc = new LocatedBlocks();
} }
isEncrypted = (feInfo != null) isEncrypted = (feInfo != null)
|| (isRawPath && FSDirEncryptionZoneOp.isInAnEZ(fsd, || (isRawPath && FSDirEncryptionZoneOp.isInAnEZ(fsd, iip));
INodesInPath.fromINode(node)));
} else { } else {
isEncrypted = FSDirEncryptionZoneOp.isInAnEZ(fsd, isEncrypted = FSDirEncryptionZoneOp.isInAnEZ(fsd, iip);
INodesInPath.fromINode(node));
} }
int childrenNum = node.isDirectory() ? int childrenNum = node.isDirectory() ?
node.asDirectory().getChildrenNum(snapshot) : 0; node.asDirectory().getChildrenNum(snapshot) : 0;

View File

@ -1665,11 +1665,11 @@ public class FSDirectory implements Closeable {
INodeAttributes getAttributes(String fullPath, byte[] path, INodeAttributes getAttributes(String fullPath, byte[] path,
INode node, int snapshot) { INode node, int snapshot) {
INodeAttributes nodeAttrs = node; INodeAttributes nodeAttrs;
if (attributeProvider != null) { if (attributeProvider != null) {
nodeAttrs = node.getSnapshotINode(snapshot); nodeAttrs = node.getSnapshotINode(snapshot);
fullPath = fullPath + (fullPath.endsWith(Path.SEPARATOR) ? "" fullPath = fullPath
: Path.SEPARATOR) + (fullPath.endsWith(Path.SEPARATOR) ? "" : Path.SEPARATOR)
+ DFSUtil.bytes2String(path); + DFSUtil.bytes2String(path);
nodeAttrs = attributeProvider.getAttributes(fullPath, nodeAttrs); nodeAttrs = attributeProvider.getAttributes(fullPath, nodeAttrs);
} else { } else {

View File

@ -371,13 +371,14 @@ public class FSEditLogLoader {
addCloseOp.atime, addCloseOp.blockSize, true, addCloseOp.atime, addCloseOp.blockSize, true,
addCloseOp.clientName, addCloseOp.clientMachine, addCloseOp.clientName, addCloseOp.clientMachine,
addCloseOp.storagePolicyId); addCloseOp.storagePolicyId);
assert newFile != null;
iip = INodesInPath.replace(iip, iip.length() - 1, newFile); iip = INodesInPath.replace(iip, iip.length() - 1, newFile);
fsNamesys.leaseManager.addLease(addCloseOp.clientName, newFile.getId()); fsNamesys.leaseManager.addLease(addCloseOp.clientName, newFile.getId());
// 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 = FSDirStatAndListingOp.createFileStatusForEditLog(
fsNamesys.dir, path, HdfsFileStatus.EMPTY_NAME, newFile, fsNamesys.dir, path, HdfsFileStatus.EMPTY_NAME,
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED, Snapshot.CURRENT_STATE_ID, HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED, Snapshot.CURRENT_STATE_ID,
false, iip); false, iip);
fsNamesys.addCacheEntryWithPayload(addCloseOp.rpcClientId, fsNamesys.addCacheEntryWithPayload(addCloseOp.rpcClientId,
@ -396,8 +397,7 @@ 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 = FSDirStatAndListingOp.createFileStatusForEditLog(
fsNamesys.dir, path, fsNamesys.dir, path, HdfsFileStatus.EMPTY_NAME,
HdfsFileStatus.EMPTY_NAME, newFile,
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED, HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED,
Snapshot.CURRENT_STATE_ID, false, iip); Snapshot.CURRENT_STATE_ID, false, iip);
fsNamesys.addCacheEntryWithPayload(addCloseOp.rpcClientId, fsNamesys.addCacheEntryWithPayload(addCloseOp.rpcClientId,
@ -470,7 +470,7 @@ 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 = FSDirStatAndListingOp.createFileStatusForEditLog(
fsNamesys.dir, path, HdfsFileStatus.EMPTY_NAME, file, fsNamesys.dir, path, HdfsFileStatus.EMPTY_NAME,
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED, HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED,
Snapshot.CURRENT_STATE_ID, false, iip); Snapshot.CURRENT_STATE_ID, false, iip);
fsNamesys.addCacheEntryWithPayload(appendOp.rpcClientId, fsNamesys.addCacheEntryWithPayload(appendOp.rpcClientId,

View File

@ -254,7 +254,7 @@ public class INodesInPath {
*/ */
public static INodesInPath append(INodesInPath iip, INode child, public static INodesInPath append(INodesInPath iip, INode child,
byte[] childName) { byte[] childName) {
Preconditions.checkArgument(!iip.isSnapshot && iip.length() > 0); Preconditions.checkArgument(iip.length() > 0);
Preconditions.checkArgument(iip.getLastINode() != null && iip Preconditions.checkArgument(iip.getLastINode() != null && iip
.getLastINode().isDirectory()); .getLastINode().isDirectory());
INode[] inodes = new INode[iip.length() + 1]; INode[] inodes = new INode[iip.length() + 1];
@ -263,7 +263,7 @@ public class INodesInPath {
byte[][] path = new byte[iip.path.length + 1][]; byte[][] path = new byte[iip.path.length + 1][];
System.arraycopy(iip.path, 0, path, 0, path.length - 1); System.arraycopy(iip.path, 0, path, 0, path.length - 1);
path[path.length - 1] = childName; path[path.length - 1] = childName;
return new INodesInPath(inodes, path, false, iip.snapshotId); return new INodesInPath(inodes, path, iip.isSnapshot, iip.snapshotId);
} }
private final byte[][] path; private final byte[][] path;