HDFS-10458. getFileEncryptionInfo should return quickly for non-encrypted cluster.

(cherry picked from commit 6de9213df111a9a4ed875db995d67af72d08a798)
(cherry picked from commit 06e38c835d0ad9619d4bea662f2dd7d0f62007a9)
This commit is contained in:
Zhe Zhang 2016-06-06 15:52:39 -07:00
parent 5b4c80b27e
commit 0499907466
2 changed files with 32 additions and 6 deletions

View File

@ -95,7 +95,7 @@ String getKeyName() {
} }
} }
private final TreeMap<Long, EncryptionZoneInt> encryptionZones; private TreeMap<Long, EncryptionZoneInt> encryptionZones = null;
private final FSDirectory dir; private final FSDirectory dir;
private final int maxListEncryptionZonesResponses; private final int maxListEncryptionZonesResponses;
@ -106,7 +106,6 @@ String getKeyName() {
*/ */
public EncryptionZoneManager(FSDirectory dir, Configuration conf) { public EncryptionZoneManager(FSDirectory dir, Configuration conf) {
this.dir = dir; this.dir = dir;
encryptionZones = new TreeMap<Long, EncryptionZoneInt>();
maxListEncryptionZonesResponses = conf.getInt( maxListEncryptionZonesResponses = conf.getInt(
DFSConfigKeys.DFS_NAMENODE_LIST_ENCRYPTION_ZONES_NUM_RESPONSES, DFSConfigKeys.DFS_NAMENODE_LIST_ENCRYPTION_ZONES_NUM_RESPONSES,
DFSConfigKeys.DFS_NAMENODE_LIST_ENCRYPTION_ZONES_NUM_RESPONSES_DEFAULT DFSConfigKeys.DFS_NAMENODE_LIST_ENCRYPTION_ZONES_NUM_RESPONSES_DEFAULT
@ -143,6 +142,9 @@ void unprotectedAddEncryptionZone(Long inodeId,
CipherSuite suite, CryptoProtocolVersion version, String keyName) { CipherSuite suite, CryptoProtocolVersion version, String keyName) {
final EncryptionZoneInt ez = new EncryptionZoneInt( final EncryptionZoneInt ez = new EncryptionZoneInt(
inodeId, suite, version, keyName); inodeId, suite, version, keyName);
if (encryptionZones == null) {
encryptionZones = new TreeMap<>();
}
encryptionZones.put(inodeId, ez); encryptionZones.put(inodeId, ez);
} }
@ -153,8 +155,10 @@ void unprotectedAddEncryptionZone(Long inodeId,
*/ */
void removeEncryptionZone(Long inodeId) { void removeEncryptionZone(Long inodeId) {
assert dir.hasWriteLock(); assert dir.hasWriteLock();
if (hasCreatedEncryptionZone()) {
encryptionZones.remove(inodeId); encryptionZones.remove(inodeId);
} }
}
/** /**
* Returns true if an IIP is within an encryption zone. * Returns true if an IIP is within an encryption zone.
@ -201,6 +205,9 @@ String getKeyName(final INodesInPath iip) {
private EncryptionZoneInt getEncryptionZoneForPath(INodesInPath iip) { private EncryptionZoneInt getEncryptionZoneForPath(INodesInPath iip) {
assert dir.hasReadLock(); assert dir.hasReadLock();
Preconditions.checkNotNull(iip); Preconditions.checkNotNull(iip);
if (!hasCreatedEncryptionZone()) {
return null;
}
List<INode> inodes = iip.getReadOnlyINodes(); List<INode> inodes = iip.getReadOnlyINodes();
for (int i = inodes.size() - 1; i >= 0; i--) { for (int i = inodes.size() - 1; i >= 0; i--) {
final INode inode = inodes.get(i); final INode inode = inodes.get(i);
@ -313,7 +320,8 @@ XAttr createEncryptionZone(String src, CipherSuite suite,
throw new IOException("Attempt to create an encryption zone for a file."); throw new IOException("Attempt to create an encryption zone for a file.");
} }
if (encryptionZones.get(srcINode.getId()) != null) { if (hasCreatedEncryptionZone() && encryptionZones.
get(srcINode.getId()) != null) {
throw new IOException("Directory " + src + " is already an encryption " + throw new IOException("Directory " + src + " is already an encryption " +
"zone."); "zone.");
} }
@ -340,6 +348,10 @@ XAttr createEncryptionZone(String src, CipherSuite suite,
BatchedListEntries<EncryptionZone> listEncryptionZones(long prevId) BatchedListEntries<EncryptionZone> listEncryptionZones(long prevId)
throws IOException { throws IOException {
assert dir.hasReadLock(); assert dir.hasReadLock();
if (!hasCreatedEncryptionZone()) {
final List<EncryptionZone> emptyZones = Lists.newArrayList();
return new BatchedListEntries<EncryptionZone>(emptyZones, false);
}
NavigableMap<Long, EncryptionZoneInt> tailMap = encryptionZones.tailMap NavigableMap<Long, EncryptionZoneInt> tailMap = encryptionZones.tailMap
(prevId, false); (prevId, false);
final int numResponses = Math.min(maxListEncryptionZonesResponses, final int numResponses = Math.min(maxListEncryptionZonesResponses,
@ -379,7 +391,18 @@ BatchedListEntries<EncryptionZone> listEncryptionZones(long prevId)
* @return number of encryption zones. * @return number of encryption zones.
*/ */
public int getNumEncryptionZones() { public int getNumEncryptionZones() {
return encryptionZones.size(); return hasCreatedEncryptionZone() ?
encryptionZones.size() : 0;
}
/**
* @return Whether there has been any attempt to create an encryption zone in
* the cluster at all. If not, it is safe to quickly return null when
* checking the encryption information of any file or directory in the
* cluster.
*/
public boolean hasCreatedEncryptionZone() {
return encryptionZones != null;
} }
/** /**
@ -387,6 +410,9 @@ public int getNumEncryptionZones() {
*/ */
String[] getKeyNames() { String[] getKeyNames() {
assert dir.hasReadLock(); assert dir.hasReadLock();
if (!hasCreatedEncryptionZone()) {
return new String[0];
}
String[] ret = new String[encryptionZones.size()]; String[] ret = new String[encryptionZones.size()];
int index = 0; int index = 0;
for (Map.Entry<Long, EncryptionZoneInt> entry : encryptionZones for (Map.Entry<Long, EncryptionZoneInt> entry : encryptionZones

View File

@ -254,7 +254,7 @@ static void setFileEncryptionInfo(final FSDirectory fsd, final String src,
static FileEncryptionInfo getFileEncryptionInfo(final FSDirectory fsd, static FileEncryptionInfo getFileEncryptionInfo(final FSDirectory fsd,
final INode inode, final int snapshotId, final INodesInPath iip) final INode inode, final int snapshotId, final INodesInPath iip)
throws IOException { throws IOException {
if (!inode.isFile()) { if (!inode.isFile() || !fsd.ezManager.hasCreatedEncryptionZone()) {
return null; return null;
} }
fsd.readLock(); fsd.readLock();