Author: eli
Date: Tue Oct 16 02:12:59 2012
New Revision: 1398612
URL: http://svn.apache.org/viewvc?rev=1398612&view=rev
Log:
HDFS-4058. DirectoryScanner may fail with IOOB if the directory scanning
threads return out of volume order. Contributed by Eli Collins
Modified:
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java
Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt?rev=1398612&r1=1398611&r2=1398612&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt (original)
+++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt Tue Oct 16
02:12:59 2012
@@ -446,6 +446,9 @@ Release 2.0.3-alpha - Unreleased
HDFS-3678. Edit log files are never being purged from 2NN. (atm)
+ HDFS-4058. DirectoryScanner may fail with IOOB if the directory
+ scanning threads return out of volume order. (eli)
+
Release 2.0.2-alpha - 2012-09-07
INCOMPATIBLE CHANGES
Modified:
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java
URL:
http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java?rev=1398612&r1=1398611&r2=1398612&view=diff
==============================================================================
---
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java
(original)
+++
hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DirectoryScanner.java
Tue Oct 16 02:12:59 2012
@@ -431,16 +431,16 @@ public class DirectoryScanner implements
private Map<String, ScanInfo[]> getDiskReport() {
// First get list of data directories
final List<? extends FsVolumeSpi> volumes = dataset.getVolumes();
- ArrayList<ScanInfoPerBlockPool> dirReports =
- new ArrayList<ScanInfoPerBlockPool>(volumes.size());
-
+
+ // Use an array since the threads may return out of order and
+ // compilersInProgress#keySet may return out of order as well.
+ ScanInfoPerBlockPool[] dirReports = new
ScanInfoPerBlockPool[volumes.size()];
+
Map<Integer, Future<ScanInfoPerBlockPool>> compilersInProgress =
new HashMap<Integer, Future<ScanInfoPerBlockPool>>();
+
for (int i = 0; i < volumes.size(); i++) {
- if (!isValid(dataset, volumes.get(i))) {
- // volume is invalid
- dirReports.add(i, null);
- } else {
+ if (isValid(dataset, volumes.get(i))) {
ReportCompiler reportCompiler =
new ReportCompiler(volumes.get(i));
Future<ScanInfoPerBlockPool> result =
@@ -452,7 +452,7 @@ public class DirectoryScanner implements
for (Entry<Integer, Future<ScanInfoPerBlockPool>> report :
compilersInProgress.entrySet()) {
try {
- dirReports.add(report.getKey(), report.getValue().get());
+ dirReports[report.getKey()] = report.getValue().get();
} catch (Exception ex) {
LOG.error("Error compiling report", ex);
// Propagate ex to DataBlockScanner to deal with
@@ -465,7 +465,7 @@ public class DirectoryScanner implements
for (int i = 0; i < volumes.size(); i++) {
if (isValid(dataset, volumes.get(i))) {
// volume is still valid
- list.addAll(dirReports.get(i));
+ list.addAll(dirReports[i]);
}
}