Przeglądaj źródła

HADOOP-4217. Checksum input stream can sometimes return invalid
data to the user. (Ning Li via rangadi)


git-svn-id: https://svn.apache.org/repos/asf/hadoop/core/branches/branch-0.17@699522 13f79535-47bb-0310-9956-ffa450edef68

Raghu Angadi 16 lat temu
rodzic
commit
a655b060e1

+ 3 - 0
CHANGES.txt

@@ -7,6 +7,9 @@ Release 0.17.3 - Unreleased
     HADOOP-4277. Checksum verification was mistakenly disabled for
     LocalFileSystem. (Raghu Angadi)
 
+    HADOOP-4217. Checksum input stream can sometimes return invalid 
+    data to the user. (Ning Li via rangadi)
+
 Release 0.17.2 - 2008-08-11
 
   BUG FIXES

+ 3 - 4
src/java/org/apache/hadoop/fs/FSInputChecker.java

@@ -174,7 +174,6 @@ abstract public class FSInputChecker extends FSInputStream {
   private void fill(  ) throws IOException {
     assert(pos>=count);
     // fill internal buffer
-    pos = 0;
     count = readChecksumChunk(buf, 0, buf.length);
   }
   
@@ -226,6 +225,9 @@ abstract public class FSInputChecker extends FSInputStream {
    */ 
   private int readChecksumChunk(byte b[], int off, int len)
   throws IOException {
+    // invalidate buffer
+    count = pos = 0;
+          
     int read = 0;
     boolean retry = true;
     int retriesLeft = numOfRetries; 
@@ -248,9 +250,6 @@ abstract public class FSInputChecker extends FSInputStream {
             throw ce;
           }
           
-          // invalidate buffer
-          count = pos = 0;
-          
           // try a new replica
           if (seekToNewSource(chunkPos)) {
             // Since at least one of the sources is different, 

+ 34 - 0
src/test/org/apache/hadoop/dfs/TestFSInputChecker.java

@@ -292,6 +292,7 @@ public class TestFSInputChecker extends TestCase {
     try {
       testChecker(fileSys, true);
       testChecker(fileSys, false);
+      testSeekAndRead(fileSys);
     } finally {
       fileSys.close();
       cluster.shutdown();
@@ -304,8 +305,41 @@ public class TestFSInputChecker extends TestCase {
       testChecker(fileSys, true);
       testChecker(fileSys, false);
       testFileCorruption((LocalFileSystem)fileSys);
+      testSeekAndRead(fileSys);
     }finally {
       fileSys.close();
     }
   }
+
+  private void testSeekAndRead(ChecksumFileSystem fileSys)
+  throws IOException {
+    Path file = new Path("try.dat");
+    writeFile(fileSys, file);
+    stm = fileSys.open(file,
+        fileSys.getConf().getInt("io.file.buffer.size", 4096));
+    checkSeekAndRead();
+    stm.close();
+    cleanupFile(fileSys, file);
+  }
+
+  private void checkSeekAndRead() throws IOException {
+    int position = 1;
+    int len = 2 * BYTES_PER_SUM - (int) position;
+    readAndCompare(stm, position, len);
+
+    position = BYTES_PER_SUM;
+    len = BYTES_PER_SUM;
+    readAndCompare(stm, position, len);
+  }
+
+  private void readAndCompare(FSDataInputStream in, int position, int len)
+      throws IOException {
+    byte[] b = new byte[len];
+    in.seek(position);
+    IOUtils.readFully(in, b, 0, b.length);
+
+    for (int i = 0; i < b.length; i++) {
+      assertEquals(expected[position + i], b[i]);
+    }
+  }
 }