|
@@ -95,7 +95,7 @@ public class EncryptionZoneManager {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- 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 @@ public class EncryptionZoneManager {
|
|
*/
|
|
*/
|
|
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 @@ public class EncryptionZoneManager {
|
|
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,7 +155,9 @@ public class EncryptionZoneManager {
|
|
*/
|
|
*/
|
|
void removeEncryptionZone(Long inodeId) {
|
|
void removeEncryptionZone(Long inodeId) {
|
|
assert dir.hasWriteLock();
|
|
assert dir.hasWriteLock();
|
|
- encryptionZones.remove(inodeId);
|
|
|
|
|
|
+ if (hasCreatedEncryptionZone()) {
|
|
|
|
+ encryptionZones.remove(inodeId);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -201,6 +205,9 @@ public class EncryptionZoneManager {
|
|
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 @@ public class EncryptionZoneManager {
|
|
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 @@ public class EncryptionZoneManager {
|
|
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 @@ public class EncryptionZoneManager {
|
|
* @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 class EncryptionZoneManager {
|
|
*/
|
|
*/
|
|
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
|