Browse Source

HDFS-12832. INode.getFullPathName may throw ArrayIndexOutOfBoundsException lead to NameNode exit. Contribuited by Konstantin Shvachko.

(cherry picked from commit d331762f24b3f22f609366740c9c4f449edc61ac)
Konstantin V Shvachko 7 years ago
parent
commit
7252e18c30

+ 16 - 12
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java

@@ -95,7 +95,6 @@ import org.apache.hadoop.util.Time;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -1475,8 +1474,6 @@ public class BlockManager {
       }
 
       // choose replication targets: NOT HOLDING THE GLOBAL LOCK
-      // It is costly to extract the filename for which chooseTargets is called,
-      // so for now we pass in the block collection itself.
       rw.chooseTargets(blockplacement, storagePolicySuite, excludedNodes);
     }
 
@@ -3708,17 +3705,15 @@ public class BlockManager {
   
 
   private static class ReplicationWork {
-
     private final Block block;
-    private final BlockCollection bc;
-
+    private final String srcPath;
+    private final byte storagePolicyID;
     private final DatanodeDescriptor srcNode;
+    private final int additionalReplRequired;
+    private final int priority;
     private final List<DatanodeDescriptor> containingNodes;
     private final List<DatanodeStorageInfo> liveReplicaStorages;
-    private final int additionalReplRequired;
-
     private DatanodeStorageInfo targets[];
-    private final int priority;
 
     public ReplicationWork(Block block,
         BlockCollection bc,
@@ -3728,7 +3723,8 @@ public class BlockManager {
         int additionalReplRequired,
         int priority) {
       this.block = block;
-      this.bc = bc;
+      this.srcPath = bc.getName();
+      this.storagePolicyID = bc.getStoragePolicyID();
       this.srcNode = srcNode;
       this.srcNode.incrementPendingReplicationWithoutTargets();
       this.containingNodes = containingNodes;
@@ -3742,14 +3738,22 @@ public class BlockManager {
         BlockStoragePolicySuite storagePolicySuite,
         Set<Node> excludedNodes) {
       try {
-        targets = blockplacement.chooseTarget(bc.getName(),
+        targets = blockplacement.chooseTarget(getSrcPath(),
             additionalReplRequired, srcNode, liveReplicaStorages, false,
             excludedNodes, block.getNumBytes(),
-            storagePolicySuite.getPolicy(bc.getStoragePolicyID()));
+            storagePolicySuite.getPolicy(getStoragePolicyID()));
       } finally {
         srcNode.decrementPendingReplicationWithoutTargets();
       }
     }
+
+    private String getSrcPath() {
+      return srcPath;
+    }
+
+    private byte getStoragePolicyID() {
+      return storagePolicyID;
+    }
   }
 
   /**