From ca1d4c46dd4cd81c46aed87cd7a52af3e6be504f Mon Sep 17 00:00:00 2001 From: Arpit Agarwal Date: Fri, 12 Oct 2018 13:33:38 -0700 Subject: [PATCH] HDDS-639. ChunkGroupInputStream gets into infinite loop after reading a block. Contributed by Mukul Kumar Singh. (cherry picked from commit 56b18b9df14b91c02cf3b7f548ab58755475b374) --- .../hadoop/ozone/client/io/ChunkGroupInputStream.java | 6 +++++- .../hadoop/fs/ozone/TestOzoneFileInterfaces.java | 11 ++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/io/ChunkGroupInputStream.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/io/ChunkGroupInputStream.java index 779161360f5..125784c46c9 100644 --- a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/io/ChunkGroupInputStream.java +++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/io/ChunkGroupInputStream.java @@ -111,7 +111,11 @@ public class ChunkGroupInputStream extends InputStream implements Seekable { } int totalReadLen = 0; while (len > 0) { - if (streamEntries.size() <= currentStreamIndex) { + // if we are at the last block and have read the entire block, return + if (streamEntries.size() == 0 || + (streamEntries.size() - 1 <= currentStreamIndex && + streamEntries.get(currentStreamIndex) + .getRemaining() == 0)) { return totalReadLen == 0 ? EOF : totalReadLen; } ChunkInputStreamEntry current = streamEntries.get(currentStreamIndex); diff --git a/hadoop-ozone/ozonefs/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFileInterfaces.java b/hadoop-ozone/ozonefs/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFileInterfaces.java index 7cf6e3d9545..217603102b5 100644 --- a/hadoop-ozone/ozonefs/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFileInterfaces.java +++ b/hadoop-ozone/ozonefs/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFileInterfaces.java @@ -174,9 +174,18 @@ public class TestOzoneFileInterfaces { try (FSDataInputStream inputStream = fs.open(path)) { byte[] buffer = new byte[stringLen]; - inputStream.readFully(0, buffer); + // This read will not change the offset inside the file + int readBytes = inputStream.read(0, buffer, 0, buffer.length); String out = new String(buffer, 0, buffer.length); assertEquals(data, out); + assertEquals(readBytes, buffer.length); + assertEquals(0, inputStream.getPos()); + + // The following read will change the internal offset + readBytes = inputStream.read(buffer, 0, buffer.length); + assertEquals(data, out); + assertEquals(readBytes, buffer.length); + assertEquals(buffer.length, inputStream.getPos()); } }