Repository navigation
HDDS-16834. Fix COMPOSITE_CRC when a block contributes no CRC bytes - #11499
jojochuang wants to merge 5 commits into
Conversation
Port the HDFS-17992 cursor-based block checksum walk so empty blocks do not misalign composite CRC assembly, and skip zero-length blocks with no chunks. Add replicated and EC regression tests. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: Ic3c039be4b464e44e4e44fd8876ba0b44f9165f2
There was a problem hiding this comment.
🟡 Changes recommended
The all-empty real execution path still throws before reaching the new fallback.
1 open finding
What changed in this PR
Fixes composite CRC calculation when empty blocks contribute no checksum bytes.
Changes:
- Skips empty block metadata safely.
- Uses a cursor for composite CRC bytes.
- Adds replicated and EC checksum tests.
| File | Description |
|---|---|
BaseFileChecksumHelper.java |
Handles empty blocks during checksum composition. |
TestFileChecksumHelper.java |
Adds empty-block checksum coverage. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Return the empty-key checksum before constructing CrcComposer when every block is skipped, so checksumType is not required. Add a test that exercises checksumBlock on empty blocks without pre-setting checksum metadata. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: I701c0e01ed34de7750433b5f51b162012cc7177a
Resolve TestFileChecksumHelper conflict: keep COMPOSITE_CRC empty-block tests and align helpers with String volume/bucket constructors on master. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: Id28507b587a57effd6f7fb7cd4e58d6d20625c1a
Detect the all-empty case via blockChecksumBuf.getLength() == 0 before constructing CrcComposer, and restore full block.getLength() composition so partial requested lengths do not produce negative update sizes. Add tests for partial length across two blocks. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: If21b9b076e968c9ad307163b5b4e1a3d9f2d819d
jojochuang
left a comment
There was a problem hiding this comment.
test self-review
Use the first non-empty block for CrcComposer size hint, add a leading empty-block test, and replace assertNotEquals(null, …) with assertNotNull. Co-authored-by: Cursor <cursoragent@cursor.com> Change-Id: I697503e632d55fc53b23c3190de01c9b618a837b
| return new MD5MD5CRC32GzipFileChecksum(0, 0, fileMD5); | ||
| } | ||
|
|
||
| private FileChecksum makeFinalResult() throws IOException { |
There was a problem hiding this comment.
Please handle empty results before the mode switch. Skipping every block leaves checksumType null and throws in MD5 mode.
| private FileChecksum makeFinalResult() throws IOException { | |
| private FileChecksum makeFinalResult() throws IOException { | |
| if (blockChecksumBuf.getLength() == 0) { | |
| // Skipped empty blocks may leave checksumType unset. | |
| return makeEmptyFileChecksum(); | |
| } |
Please also test RATIS/EC × both modes through checksumBlock(); the MD5 fake pre-sets the type.
| FileChecksum makeCompositeCrcResult() throws IOException { | ||
| if (blockChecksumBuf.getLength() == 0) { | ||
| // Every block is empty, e.g. a zero-length key whose writer died | ||
| // after allocating a block. Treat it like a key without blocks. | ||
| // Detect this before constructing CrcComposer because skipped empty | ||
| // blocks never set checksumType. | ||
| return makeEmptyFileChecksum(); | ||
| } |
There was a problem hiding this comment.
Please remove this guard after moving it to makeFinalResult().
| FileChecksum makeCompositeCrcResult() throws IOException { | |
| if (blockChecksumBuf.getLength() == 0) { | |
| // Every block is empty, e.g. a zero-length key whose writer died | |
| // after allocating a block. Treat it like a key without blocks. | |
| // Detect this before constructing CrcComposer because skipped empty | |
| // blocks never set checksumType. | |
| return makeEmptyFileChecksum(); | |
| } | |
| FileChecksum makeCompositeCrcResult() throws IOException { |

Summary
BaseFileChecksumHelper#makeCompositeCrcResultto walk block checksum bytes with a cursor and skip blocks that contribute no composite CRC bytes (same approach as HDFS-17992).Jira
https://issues.apache.org/jira/browse/HDDS-16834
Test plan
mvn -pl :ozone-client test -Dtest=TestFileChecksumHelper -DskipShade -DskipRecon -DskipDocs./hadoop-ozone/dev-support/checks/checkstyle.shGenerated-by: Cursor (Auto)
Made with Cursor