diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java index 16b79539fdd55..2cbe6bd0e3e63 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java @@ -2550,16 +2550,18 @@ DatanodeDescriptor[] chooseSourceDatanodes(BlockInfo block, BitSet liveBitSet = null; BitSet decommissioningBitSet = null; + HashSet haveComputedAsCorrupted = null; if (isStriped) { int blockNum = ((BlockInfoStriped) block).getTotalBlockNum(); liveBitSet = new BitSet(blockNum); decommissioningBitSet = new BitSet(blockNum); + haveComputedAsCorrupted = new HashSet<>(); } for (DatanodeStorageInfo storage : blocksMap.getStorages(block)) { final DatanodeDescriptor node = getDatanodeDescriptorFromStorage(storage); final StoredReplicaState state = checkReplicaOnStorage(numReplicas, block, - storage, corruptReplicas.getNodes(block), false); + storage, corruptReplicas.getNodes(block), false, haveComputedAsCorrupted); if (state == StoredReplicaState.LIVE) { if (storage.getStorageType() == StorageType.PROVIDED) { storage = new DatanodeStorageInfo(node, storage.getStorageID(), @@ -4544,13 +4546,15 @@ public NumberReplicas countNodes(BlockInfo b) { NumberReplicas countNodes(BlockInfo b, boolean inStartupSafeMode) { NumberReplicas numberReplicas = new NumberReplicas(); Collection nodesCorrupt = corruptReplicas.getNodes(b); + HashSet haveComputedAsCorrupted = null; if (b.isStriped()) { + haveComputedAsCorrupted = new HashSet<>(); countReplicasForStripedBlock(numberReplicas, (BlockInfoStriped) b, - nodesCorrupt, inStartupSafeMode); + nodesCorrupt, inStartupSafeMode, haveComputedAsCorrupted); } else { for (DatanodeStorageInfo storage : blocksMap.getStorages(b)) { checkReplicaOnStorage(numberReplicas, b, storage, nodesCorrupt, - inStartupSafeMode); + inStartupSafeMode, haveComputedAsCorrupted); } } return numberReplicas; @@ -4558,11 +4562,16 @@ NumberReplicas countNodes(BlockInfo b, boolean inStartupSafeMode) { private StoredReplicaState checkReplicaOnStorage(NumberReplicas counters, BlockInfo b, DatanodeStorageInfo storage, - Collection nodesCorrupt, boolean inStartupSafeMode) { + Collection nodesCorrupt, boolean inStartupSafeMode, + HashSet haveComputedAsCorrupted) { final StoredReplicaState s; if (storage.getState() == State.NORMAL) { final DatanodeDescriptor node = storage.getDatanodeDescriptor(); - if (nodesCorrupt != null && nodesCorrupt.contains(node)) { + if (nodesCorrupt != null && nodesCorrupt.contains(node) && + (haveComputedAsCorrupted == null || !haveComputedAsCorrupted.contains(node))) { + if (haveComputedAsCorrupted != null) { + haveComputedAsCorrupted.add(node); + } s = StoredReplicaState.CORRUPT; } else if (inStartupSafeMode) { s = StoredReplicaState.LIVE; @@ -4608,12 +4617,12 @@ private StoredReplicaState checkReplicaOnStorage(NumberReplicas counters, */ private void countReplicasForStripedBlock(NumberReplicas counters, BlockInfoStriped block, Collection nodesCorrupt, - boolean inStartupSafeMode) { + boolean inStartupSafeMode, HashSet haveComputedAsCorrupted) { BitSet liveBitSet = new BitSet(block.getTotalBlockNum()); BitSet decommissioningBitSet = new BitSet(block.getTotalBlockNum()); for (StorageAndBlockIndex si : block.getStorageAndIndexInfos()) { StoredReplicaState state = checkReplicaOnStorage(counters, block, - si.getStorage(), nodesCorrupt, inStartupSafeMode); + si.getStorage(), nodesCorrupt, inStartupSafeMode, haveComputedAsCorrupted); countLiveAndDecommissioningReplicas(counters, state, liveBitSet, decommissioningBitSet, si.getBlockIndex()); }