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]