This is an automated email from the ASF dual-hosted git repository.

chungen0126 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 037f9161a33 HDDS-16704. ReadBlock fails with IllegalStateException 
when a response is shorter than responseDataSize (#11402)
037f9161a33 is described below

commit 037f9161a333cb4bb9eb0e0d3a72fcea352e8b12
Author: Sergey Soldatov <[email protected]>
AuthorDate: Sun Oct 4 08:04:36 2026 -0700

    HDDS-16704. ReadBlock fails with IllegalStateException when a response is 
shorter than responseDataSize (#11402)
---
 .../ozone/container/keyvalue/ReadBlockComputation.java |  8 +++++---
 .../ozone/container/keyvalue/TestKeyValueHandler.java  | 18 ++++++++++++++++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/ReadBlockComputation.java
 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/ReadBlockComputation.java
index b08e9062ac0..de5cb5e46fd 100644
--- 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/ReadBlockComputation.java
+++ 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/ReadBlockComputation.java
@@ -123,16 +123,18 @@ public int computeBufferLimit(long offset, long 
remainingLength) {
      * - Current offset = 0, responseDataSize = 20
      *
      * If using an INCLUSIVE boundary (end = 20 - 1 = 19):
-     * - endChunk = findChunk(19) -> Chunk 1 (offset = 0)
+     * - endChunk = searchChunk(19) -> Chunk 1 (offset = 0)
      * - lengthExcludingEndChunk = 0 - 0 = 0
      * - Result = ((20 - 0) & -16) + 0 = 16 (Incorrectly truncates 4 bytes)
      *
      * If using an EXCLUSIVE boundary (end = 20):
-     * - endChunk = findChunk(20) -> Chunk 2 (offset = 20)
+     * - endChunk = searchChunk(20) -> Chunk 2 (offset = 20)
      * - lengthExcludingEndChunk = 20 - 0 = 20
      * - Result = ((20 - 20) & -16) + 20 = 20 (Correctly reads the entire 
Chunk 1)
+     *
+     * Use searchChunk, not findChunk: the read may stop before this end, so 
the findChunk cursor must not move here.
      */
-    ChunkInfo endChunk = chunks.get(findChunk(offset + responseDataSize));
+    ChunkInfo endChunk = chunks.get(searchChunk(offset + responseDataSize, 
chunks));
     final int lengthExcludingEndChunk = Math.toIntExact(endChunk.getOffset() - 
offset);
     // bytesPerChecksum must be a power of 2.
     return ((responseDataSize - lengthExcludingEndChunk) & bitMask) + 
lengthExcludingEndChunk;
diff --git 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueHandler.java
 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueHandler.java
index 4418c0a282b..c35c003141c 100644
--- 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueHandler.java
+++ 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueHandler.java
@@ -1210,6 +1210,24 @@ public void 
testReadBlockErrorOnTheStreamClosesTheBlockFile() throws Exception {
     }
   }
 
+  /**
+   * A chunk boundary inside the response window that is not checksum aligned 
makes a response shorter than
+   * responseDataSize; the next response must continue from where the short 
one stopped.
+   */
+  @Test
+  public void testReadBlockResponseShorterThanResponseDataSize() throws 
Exception {
+    final int unit = (int) BYTES_PER_CHECKSUM;
+    try (StreamFixture fixture = new StreamFixture()) {
+      fixture.appendChunk("chunk1", 0, unit);
+      fixture.appendChunk("chunk2", unit, 20);
+      fixture.appendChunk("chunk3", unit + 20, unit);
+      final long blockSize = 2L * unit + 20;
+      ReadBlockResult result = fixture.read(0, blockSize, 2 * unit);
+      assertResponses(result, 0, blockSize);
+      assertEquals(unit + 20, 
result.getDataResponses().get(0).getReadBlock().getData().size());
+    }
+  }
+
   /** Each byte of the block is the low byte of its position. */
   private static byte[] writtenBytes(long offset, int length) {
     final byte[] bytes = new byte[length];


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to