Browse Source

HADOOP-3571. Fix bug in block removal used in lease recovery. Contributed by Konstantin Shvachko.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/core/trunk@670709 13f79535-47bb-0310-9956-ffa450edef68
Konstantin Shvachko 17 years ago
parent
commit
e033daf9ac

+ 2 - 0
CHANGES.txt

@@ -707,6 +707,8 @@ Release 0.17.1 - Unreleased
     HADOOP-3537. Disallow adding a datanode to a network topology when its
     network location is not resolved. (hairong)
 
+    HADOOP-3571. Fix bug in block removal used in lease recovery. (shv)
+
 Release 0.17.0 - 2008-05-18
 
   INCOMPATIBLE CHANGES

+ 12 - 15
src/hdfs/org/apache/hadoop/dfs/BlocksMap.java

@@ -156,11 +156,7 @@ class BlocksMap {
      * Remove data-node from the block.
      */
     boolean removeNode(DatanodeDescriptor node) {
-      return removeNode(findDatanode(node));
-    }
-
-    /** Remove the indexed datanode from the block. */
-    boolean removeNode(int dnIndex) {
+      int dnIndex = findDatanode(node);
       if(dnIndex < 0) // the node is not found
         return false;
       assert getPrevious(dnIndex) == null && getNext(dnIndex) == null : 
@@ -336,18 +332,19 @@ class BlocksMap {
   }
 
   /**
-   * Remove the block from the block map.
-   * If the mapped BlockInfo is not null,
-   * it also removes the datanodes associated with the BlockInfo. 
+   * Remove the block from the block map;
+   * remove it from all data-node lists it belongs to;
+   * and remove all data-node locations associated with the block.
    */
-  void remove(Block b) {
-    BlockInfo info = map.remove(b);
-    if (info != null) {
-      info.inode = null;
-      for(int n = info.numNodes(); n >= 0; ) {
-        info.removeNode(--n);
-      }
+  void removeBlock(BlockInfo blockInfo) {
+    if (blockInfo == null)
+      return;
+    blockInfo.inode = null;
+    for(int idx = blockInfo.numNodes()-1; idx >= 0; idx--) {
+      DatanodeDescriptor dn = blockInfo.getDatanode(idx);
+      dn.removeBlock(blockInfo); // remove from the list and wipe the location
     }
+    map.remove(blockInfo);  // remove block from the map
   }
 
   /** Returns the block object it it exists in the map. */

+ 2 - 2
src/hdfs/org/apache/hadoop/dfs/FSNamesystem.java

@@ -1716,8 +1716,8 @@ class FSNamesystem implements FSConstants, FSNamesystemMBean {
     INodeFileUnderConstruction pendingFile = (INodeFileUnderConstruction)iFile;
 
     // Remove old block from blocks map. This always have to be done
-    // because the generationstamp of this block is changing.
-    blocksMap.remove(lastblock);
+    // because the generation stamp of this block is changing.
+    blocksMap.removeBlock(oldblockinfo);
 
     if (deleteblock) {
       pendingFile.removeBlock(lastblock);