Browse Source

HADOOP-3614. Fix a bug that Datanode may use an old GenerationStamp to get meta file. (szetszwo)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/core/branches/branch-0.18@699679 13f79535-47bb-0310-9956-ffa450edef68
Tsz-wo Sze 16 years ago
parent
commit
0cdb0a3e8b

+ 3 - 0
CHANGES.txt

@@ -6,6 +6,9 @@ Release 0.18.2 - Unreleased
 
     HADOOP-4116. Balancer should provide better resource management. (hairong)
 
+    HADOOP-3614. Fix a bug that Datanode may use an old GenerationStamp to get
+    meta file. (szetszwo)
+
   NEW FEATURES
 
     HADOOP-2421.  Add jdiff output to documentation, listing all API

+ 14 - 12
src/hdfs/org/apache/hadoop/dfs/FSDataset.java

@@ -606,9 +606,10 @@ class FSDataset implements FSConstants, FSDatasetInterface {
     }
   }
 
-  File findBlockFile(Block b) {
-    assert b.generationStamp == GenerationStamp.WILDCARD_STAMP;
-
+  /** Return the block file for the given ID */ 
+  public File findBlockFile(long blockId) {
+    final Block b = new Block(blockId);
+     
     File blockfile = null;
     ActiveFile activefile = ongoingCreates.get(b);
     if (activefile != null) {
@@ -627,16 +628,14 @@ class FSDataset implements FSConstants, FSDatasetInterface {
   }
 
   /** {@inheritDoc} */
-  public Block getStoredBlock(long blkid) throws IOException {
-    Block b = new Block(blkid);
-    File blockfile = findBlockFile(b);
+  public synchronized Block getStoredBlock(long blkid) throws IOException {
+    File blockfile = findBlockFile(blkid);
     if (blockfile == null) {
       return null;
     }
     File metafile = findMetaFile(blockfile);
-    b.generationStamp = parseGenerationStamp(blockfile, metafile);
-    b.len = blockfile.length();
-    return b;
+    return new Block(blkid, blockfile.length(),
+        parseGenerationStamp(blockfile, metafile));
   }
 
   public boolean metaFileExists(Block b) throws IOException {
@@ -791,10 +790,13 @@ class FSDataset implements FSConstants, FSDatasetInterface {
           + ") to newblock (=" + newblock + ").");
     }
 
-    File blockFile = findBlockFile(oldblock);
+    File blockFile = findBlockFile(oldblock.getBlockId());
+    if (blockFile == null) {
+      throw new IOException("Block " + oldblock + " does not exist.");
+    }
     interruptOngoingCreates(oldblock);
-    
-    File oldMetaFile = getMetaFile(blockFile, oldblock);
+
+    File oldMetaFile = findMetaFile(blockFile);
     long oldgs = parseGenerationStamp(blockFile, oldMetaFile);
     
     //rename meta file to a tmp file

+ 11 - 5
src/test/org/apache/hadoop/dfs/TestFileCreation.java

@@ -17,15 +17,21 @@
  */
 package org.apache.hadoop.dfs;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.util.Random;
 
+import org.apache.commons.logging.impl.Log4JLogger;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.*;
+import org.apache.hadoop.fs.BlockLocation;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.IOUtils;
-
-import org.apache.commons.logging.impl.Log4JLogger;
 import org.apache.log4j.Level;
 
 
@@ -668,7 +674,7 @@ public class TestFileCreation extends junit.framework.TestCase {
         DataNode datanode = cluster.getDataNode(datanodeinfo.ipcPort);
         FSDataset dataset = (FSDataset)datanode.data;
         Block b = dataset.getStoredBlock(locatedblock.getBlock().blkid);
-        File blockfile = dataset.findBlockFile(b);
+        File blockfile = dataset.findBlockFile(b.getBlockId());
         System.out.println("blockfile=" + blockfile);
         if (blockfile != null) {
           BufferedReader in = new BufferedReader(new FileReader(blockfile));