[ 
https://issues.apache.org/jira/browse/HDDS-16258?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Chu Cheng Li updated HDDS-16258:
--------------------------------
    Description: 
Streaming ReadBlock can fail checksum verification for valid data after 
flush/hsync produces uneven chunks. Checksum intervals restart at each chunk, 
so flattening the stored checksums and verifying the response as one continuous 
sequence gives incorrect boundaries.

HDDS-15857 added server-side range alignment and shared per-chunk verification. 
It did not add chunk metadata to the response protocol or update client 
verification; the production path still uses the legacy flattened checksum 
collector.

For example, with bytesPerChecksum=4:
{noformat}
Stored chunks:       [A B C D E] [F G H I J K L]
Stored CRC ranges:   [ABCD] [E] [FGHI] [JKL]
Flat client ranges:  [ABCD] [EFGH] [IJKL]
{noformat}

The fix has two parts:
# Refactor {{KeyValueHandler#readBlockImpl}} by evolving 
{{ReadBlockComputation}} into one {{BlockReadCursor}} that owns aligned 
offsets, response lengths, overlapping chunk selection, and read progress.
# Replace the flattened response checksum field with metadata for only the 
chunks overlapping each response. Preserve their original offsets and stored 
checksums, and use {{Checksum.validateChecksums}} on both the server and 
{{StreamBlockInputStream}} to verify each range relative to its chunk.

Cover shifted starts, short final checksum intervals, {{NONE}}, empty data, and 
missing or incomplete metadata. Verification must preserve buffer positions and 
reject checksum failures before the client enqueues data. Keep the existing 
verification settings and stream error/cleanup behavior; fail unexpected EOF 
before sending an incomplete checksum interval. Remove {{testVariableChunks}} 
and exercise the same production path in tests, including uneven persisted 
chunks and full/seek/range reads.

The proposed streaming response change intentionally requires matching client 
and datanode implementations, with no legacy fallback. Streaming reads are 
disabled by default. Keep {{proto.lock}} unchanged until the next release. This 
ticket is limited to the cursor refactor and checksum correctness in streaming 
ReadBlock; general request validation, ordinary chunk reads, and the stored 
format are outside its scope.

  was:
*Description:*

*Background* As part of HDDS-15857, we fixed the server-side checksum 
calculation in {{KeyValueHandler}} for variable-sized chunks and updated the 
protocol to optionally include {{chunkInfoList}} in the 
{{{}ReadBlockResponseProto{}}}. To keep the original patch focused and 
manageable, the client-side verification logic has been split into this ticket.

*Problem* Currently, when a client actively triggers a flush or hsync, the 
resulting chunk size may not perfectly align with {{{}bytesPerChunk{}}}. The 
client-side {{StreamBlockInputStream}} incorrectly assumes all chunks (except 
the last one) have a fixed size when verifying checksums.

Because of this fixed-size assumption, the client cannot correctly map the 
offsets for variable-sized chunks. This leads to misaligned checksum 
verification, causing false {{{}OzoneChecksumException{}}}s when processing 
chunks that are variable-sized or smaller than {{{}bytesPerChunk{}}}.

*Proposed Solution* Update the client-side streaming read architecture to be 
aware of exact chunk boundaries:
 # *Boundary-Aware Verification:* In {{{}StreamBlockInputStream#onNext{}}}, if 
the server response contains {{chunkInfoList}} and checksum verification is 
enabled:

 ** Iterate through each chunk to identify the exact overlapping region between 
the read block and the chunk boundaries.

 ** Calculate the correct start and end checksum indices using 
{{bytesPerChecksum}} relative to that specific chunk's starting offset.

 # *Backward Compatibility:* If {{chunkInfoList}} is absent from the response 
(e.g., when reading from an older DataNode version), the client must gracefully 
fall back to the legacy verification path ({{{}Checksum.verifyChecksum(data, 
checksumData, 0){}}}) to avoid breaking upgrades.

*Testing*
 * Update {{TestStreamBlockInputStream.java}} to validate boundary-aware 
verification using {{{}chunkInfoList{}}}.

 * Add integration tests in {{TestStreamRead.java}} (e.g., 
{{testSmallChunksWithLargeChecksum}} and 
{{{}testShiftedChecksumBoundaryVerification{}}}) to cover varying/small chunk 
sizes with larger {{{}bytesPerChecksum{}}}.

        Summary: Refactor streaming block reads and fix checksum verification 
for variable-sized chunks  (was: Support boundary-aware checksum verification 
for variable-sized chunks in StreamBlockInputStream)

> Refactor streaming block reads and fix checksum verification for 
> variable-sized chunks
> --------------------------------------------------------------------------------------
>
>                 Key: HDDS-16258
>                 URL: https://issues.apache.org/jira/browse/HDDS-16258
>             Project: Apache Ozone
>          Issue Type: Sub-task
>            Reporter: Chung-En Lee
>            Assignee: Chung-En Lee
>            Priority: Major
>              Labels: pull-request-available
>
> Streaming ReadBlock can fail checksum verification for valid data after 
> flush/hsync produces uneven chunks. Checksum intervals restart at each chunk, 
> so flattening the stored checksums and verifying the response as one 
> continuous sequence gives incorrect boundaries.
> HDDS-15857 added server-side range alignment and shared per-chunk 
> verification. It did not add chunk metadata to the response protocol or 
> update client verification; the production path still uses the legacy 
> flattened checksum collector.
> For example, with bytesPerChecksum=4:
> {noformat}
> Stored chunks:       [A B C D E] [F G H I J K L]
> Stored CRC ranges:   [ABCD] [E] [FGHI] [JKL]
> Flat client ranges:  [ABCD] [EFGH] [IJKL]
> {noformat}
> The fix has two parts:
> # Refactor {{KeyValueHandler#readBlockImpl}} by evolving 
> {{ReadBlockComputation}} into one {{BlockReadCursor}} that owns aligned 
> offsets, response lengths, overlapping chunk selection, and read progress.
> # Replace the flattened response checksum field with metadata for only the 
> chunks overlapping each response. Preserve their original offsets and stored 
> checksums, and use {{Checksum.validateChecksums}} on both the server and 
> {{StreamBlockInputStream}} to verify each range relative to its chunk.
> Cover shifted starts, short final checksum intervals, {{NONE}}, empty data, 
> and missing or incomplete metadata. Verification must preserve buffer 
> positions and reject checksum failures before the client enqueues data. Keep 
> the existing verification settings and stream error/cleanup behavior; fail 
> unexpected EOF before sending an incomplete checksum interval. Remove 
> {{testVariableChunks}} and exercise the same production path in tests, 
> including uneven persisted chunks and full/seek/range reads.
> The proposed streaming response change intentionally requires matching client 
> and datanode implementations, with no legacy fallback. Streaming reads are 
> disabled by default. Keep {{proto.lock}} unchanged until the next release. 
> This ticket is limited to the cursor refactor and checksum correctness in 
> streaming ReadBlock; general request validation, ordinary chunk reads, and 
> the stored format are outside its scope.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

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

Reply via email to