Skip to content

HDDS-13919. S3 Conditional Writes (PutObject) [2/2] - Reuse Atomic Rewrite at Commit Path#10023

Merged
peterxcli merged 2 commits intoapache:masterfrom
peterxcli:HDDS-13919-conditional-writes
Apr 3, 2026
Merged

HDDS-13919. S3 Conditional Writes (PutObject) [2/2] - Reuse Atomic Rewrite at Commit Path#10023
peterxcli merged 2 commits intoapache:masterfrom
peterxcli:HDDS-13919-conditional-writes

Conversation

@peterxcli
Copy link
Copy Markdown
Member

What changes were proposed in this pull request?

OM Create Phase
Validation is performed within the validateAndUpdateCache method to ensure atomicity within the Ratis state machine application.

  1. Locking: The OM acquires the write lock for the bucket/key.
  2. Key Lookup: Retrieve the existing key from KeyTable.
  3. Validation:
    • Key Not Found: If the key does not exist, throw KEY_NOT_FOUND (maps to S3 412).
    • No ETag Metadata: If the existing key (e.g., uploaded via OFS) does not have an ETag property, throw ETAG_NOT_AVAILABLE (maps to S3 412). The precondition cannot be evaluated, so we must fail rather than silently proceed.
    • ETag Mismatch: Compare existingKey.ETag with expectedETag. If they do not match, throw ETAG_MISMATCH (maps to S3 412).
  4. Extract Generation: If ETag matches, extract existingKey.updateID.
  5. Create Open Key: Create open key entry with expectedDataGeneration = existingKey.updateID.

Sorry I forgot to follow the step 4 and 5 in my previous PR #9815 ...

What is the link to the Apache JIRA

issues.apache.org/jira/browse/HDDS-13919

How was this patch tested?

existing tests

@peterxcli peterxcli changed the title HDDS-13919. S3 Conditional Writes (PutObject) [1/2] - Reuse Atomic Rewrite at Commit Path HDDS-13919. S3 Conditional Writes (PutObject) [2/2] - Reuse Atomic Rewrite at Commit Path Apr 1, 2026
@peterxcli peterxcli marked this pull request as ready for review April 1, 2026 18:15
throw new OMException("ETag mismatch",
OMException.ResultCodes.ETAG_MISMATCH);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

it seems like the same logic ad in CommitRequest

Copy link
Copy Markdown
Member Author

@peterxcli peterxcli Apr 2, 2026

Choose a reason for hiding this comment

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

correct, and that's actually unnecessary as the reason I wrote in the description.

  1. Extract Generation: If ETag matches, extract existingKey.updateID.
  2. Create Open Key: Create open key entry with expectedDataGeneration = existingKey.updateID.

Copy link
Copy Markdown
Contributor

@ivandika3 ivandika3 Apr 3, 2026

Choose a reason for hiding this comment

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

Ok after thinking a bit more, I think using expectedDataGeneration ensure that only one PutObject can succeed even if two PutObject are using the same valid If-Match.

From the if-match semantic, if there are two concurrent clients that are calling PutObject with the same if-match, both should succeed since the ETag is the same although expectedDataGeneration are not the same.

So in the end, our implementation of if-match is more strict (not necessarily a bad thing). However, it might cause duplicated requests to be rejected. Let me know what you think.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

From the if-match semantic, if there are two concurrent clients that are calling PutObject with the same if-match, both should succeed since the ETag is the same although expectedDataGeneration are not the same.

This would only be true if the ETag of the object didn't change upon a successful (Conditional) PutObject.

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.

Yes, overall I'm OK with the current approach.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

However, it might cause duplicated requests to be rejected

let me think about which applications built on top of the AWS S3 spec would be affected by this stricter semantics.

Copy link
Copy Markdown
Member Author

@peterxcli peterxcli Apr 3, 2026

Choose a reason for hiding this comment

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

@ivandika3 The only thing I can think of is that the AWS behavior can suffer from the ABA problem if duplicate conditional PutObject requests are not rejected. In contrast, our version behaves more like a tagged pointer, which prevents the ABA scenario. So everything else stays the same; only concurrent duplicate or ABA-style requests gain a stronger safety guarantee.

@peterxcli peterxcli requested review from sodonnel and yandrey321 and removed request for yandrey321 April 2, 2026 04:11
Copy link
Copy Markdown
Contributor

@ivandika3 ivandika3 left a comment

Choose a reason for hiding this comment

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

@peterxcli Thanks for the patch.

throw new OMException("ETag mismatch",
OMException.ResultCodes.ETAG_MISMATCH);
}
}
Copy link
Copy Markdown
Contributor

@ivandika3 ivandika3 Apr 3, 2026

Choose a reason for hiding this comment

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

Ok after thinking a bit more, I think using expectedDataGeneration ensure that only one PutObject can succeed even if two PutObject are using the same valid If-Match.

From the if-match semantic, if there are two concurrent clients that are calling PutObject with the same if-match, both should succeed since the ETag is the same although expectedDataGeneration are not the same.

So in the end, our implementation of if-match is more strict (not necessarily a bad thing). However, it might cause duplicated requests to be rejected. Let me know what you think.

@peterxcli peterxcli requested a review from ivandika3 April 3, 2026 08:13
Copy link
Copy Markdown
Contributor

@ivandika3 ivandika3 left a comment

Choose a reason for hiding this comment

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

LGTM +1.

@peterxcli peterxcli merged commit 6a32869 into apache:master Apr 3, 2026
87 of 89 checks passed
@peterxcli peterxcli deleted the HDDS-13919-conditional-writes branch April 3, 2026 09:14
@peterxcli
Copy link
Copy Markdown
Member Author

Thanks @ivandika3 and @yandrey321 for the review!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants