diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java index 58071dc67d..e2baf32ff2 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java @@ -22,6 +22,7 @@ import java.io.FilenameFilter; import java.io.IOException; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -398,14 +399,13 @@ private void scan() { diffs.put(bpid, diffRecord); statsRecord.totalBlocks = blockpoolReport.length; - List bl = dataset.getFinalizedBlocks(bpid); - ReplicaInfo[] memReport = bl.toArray(new ReplicaInfo[bl.size()]); - Arrays.sort(memReport); // Sort based on blockId + final List bl = dataset.getFinalizedBlocks(bpid); + Collections.sort(bl); // Sort based on blockId int d = 0; // index for blockpoolReport int m = 0; // index for memReprot - while (m < memReport.length && d < blockpoolReport.length) { - ReplicaInfo memBlock = memReport[m]; + while (m < bl.size() && d < blockpoolReport.length) { + ReplicaInfo memBlock = bl.get(m); ScanInfo info = blockpoolReport[d]; if (info.getBlockId() < memBlock.getBlockId()) { if (!dataset.isDeletingBlock(bpid, info.getBlockId())) { @@ -452,8 +452,8 @@ private void scan() { ++m; } } - while (m < memReport.length) { - ReplicaInfo current = memReport[m++]; + while (m < bl.size()) { + ReplicaInfo current = bl.get(m++); addDifference(diffRecord, statsRecord, current.getBlockId(), current.getVolume()); } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/FsDatasetSpi.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/FsDatasetSpi.java index f2ffa833cf..e11321246b 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/FsDatasetSpi.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/FsDatasetSpi.java @@ -229,7 +229,16 @@ StorageReport[] getStorageReports(String bpid) */ VolumeFailureSummary getVolumeFailureSummary(); - /** @return a list of finalized blocks for the given block pool. */ + /** + * Gets a list of references to the finalized blocks for the given block pool. + *

+ * Callers of this function should call + * {@link FsDatasetSpi#acquireDatasetLock} to avoid blocks' status being + * changed during list iteration. + *

+ * @return a list of references to the finalized blocks for the given block + * pool. + */ List getFinalizedBlocks(String bpid); /** @return a list of finalized blocks for the given block pool. */ diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java index abeda2ca9e..0f40f2a2dc 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java @@ -1714,17 +1714,23 @@ public Map getBlockReports(String bpid) { } /** - * Get the list of finalized blocks from in-memory blockmap for a block pool. + * Gets a list of references to the finalized blocks for the given block pool. + *

+ * Callers of this function should call + * {@link FsDatasetSpi#acquireDatasetLock} to avoid blocks' status being + * changed during list iteration. + *

+ * @return a list of references to the finalized blocks for the given block + * pool. */ @Override public List getFinalizedBlocks(String bpid) { try (AutoCloseableLock lock = datasetLock.acquire()) { - ArrayList finalized = - new ArrayList(volumeMap.size(bpid)); + final List finalized = new ArrayList( + volumeMap.size(bpid)); for (ReplicaInfo b : volumeMap.replicas(bpid)) { if (b.getState() == ReplicaState.FINALIZED) { - finalized.add(new ReplicaBuilder(ReplicaState.FINALIZED) - .from(b).build()); + finalized.add(b); } } return finalized;