Skip to content

HDDS-16834. Fix COMPOSITE_CRC when a block contributes no CRC bytes - #11499

Open
jojochuang wants to merge 5 commits into
apache:masterfrom
jojochuang:HDDS-16834
Open

jojochuang wants to merge 5 commits into
apache:masterfrom
jojochuang:HDDS-16834

Conversation

@jojochuang

Copy link
Copy Markdown
Contributor

Summary

  • Fix BaseFileChecksumHelper#makeCompositeCrcResult to walk block checksum bytes with a cursor and skip blocks that contribute no composite CRC bytes (same approach as HDFS-17992).
  • Skip zero-length blocks with no chunk metadata instead of failing checksum collection early.
  • Tolerate empty block checksums in debug logging for COMPOSITE_CRC mode.
  • Add unit tests for replicated and EC layouts covering empty blocks at the end, in the middle, and on zero-length keys.

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.sh

Generated-by: Cursor (Auto)

Made with Cursor

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
Copilot AI balanced review requested due to automatic review settings October 12, 2026 19:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 jojochuang left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
@jojochuang
jojochuang requested a review from rich7420 October 16, 2026 23:52
return new MD5MD5CRC32GzipFileChecksum(0, 0, fileMD5);
}

private FileChecksum makeFinalResult() throws IOException {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please handle empty results before the mode switch. Skipping every block leaves checksumType null and throws in MD5 mode.

Suggested change
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.

Comment on lines 383 to +390
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();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this guard after moving it to makeFinalResult().

Suggested change
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 {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants