Skip to content

posix: implement Af2MPUHandler (write-at-offset, stash-the-tail) for AF2/SDFS#4

Open
riaarora-boop wants to merge 2 commits into
feat/posix-mpu-handlerfrom
feat/posix-af2-mpu-handler
Open

posix: implement Af2MPUHandler (write-at-offset, stash-the-tail) for AF2/SDFS#4
riaarora-boop wants to merge 2 commits into
feat/posix-mpu-handlerfrom
feat/posix-af2-mpu-handler

Conversation

@riaarora-boop

Copy link
Copy Markdown

Summary:

Adds Af2MPUHandler, a concrete MPUHandler for Rubrik CDM SDFS AF2 channels. Activated automatically when SameDirTmp=true.

Write-at-offset: Instead of staging one file per part and concatenating at Complete (two full-size writes), every part is written directly at its computed final byte offset in a single data file, revealed with a same-directory rename at Complete — one write per byte, no staging copy.

Stash-the-tail: Parts that arrive before the stride is resolvable (or that are shorter than the confirmed stride) are appended to a per-upload stash file and folded into the data file at Complete with an fsync before the index flip.

O(1) CompleteMultipartUpload: Each part's CRC64NVME is recorded in the per-upload index at UploadPart time (otterMpuPart.CRC). validateRevealMpu accumulates the full-object CRC from stored per-part values with no data re-read — O(parts), not O(bytes). Fixes a ~16 min stall at 100 GiB that exceeded S3 client timeouts.

Fsync durability: writeDurableAtomic fsyncs the temp fd and parent dir before returning. uploadPartAtOffset fsyncs the part data before committing its index record. Fold steps fsync the data file before flipping the stash flag. PutObject fsyncs via the postprocess hook. The SDFS RS-sync regression that originally required removing fsync (CDM-550864) has been reverted (scaledata/sdmain#226685).

Test Plan:

  • go test ./backend/posix/... passes (MPU write-at-offset, stash-the-tail, stride inference, O(1) Complete, abort/list all covered)
  • Validated end-to-end on cluster: real Postgres WAL archive through versitygw into an AF2 partition, checkpoint verified

JIRA Issues:

CDM-557245 (subtask of CDM-557238)

Revert Plan:

Revert this PR. Af2MPUHandler is only activated when SameDirTmp=true; standard posix deployments are unaffected.

riaarora-boop and others added 2 commits July 9, 2026 15:48
…AF2/SDFS

Adds Af2MPUHandler, a concrete MPUHandler for Rubrik CDM SDFS AF2 channels.
Instead of staging one file per part and concatenating at Complete, every
part is written directly at its final byte offset in a single data file,
revealed with a same-directory rename — one write per byte, no staging copy.

Stride inference (from part #1 or from the max of any two distinct parts)
places full-size parts at their final offset immediately. Parts that arrive
before the stride is resolvable, or that are shorter than the confirmed
stride (the tail), are appended to a per-upload stash file and folded at
Complete. No fsync: durability is deferred to the AF2 checkpoint (ack-on-write).

Also extends MPUHandler with CreateMultipartUpload so the Af2 path can
capture upload metadata as plain files (AF2 DESC xattr is not writable on
directories). ListMultipartUploads updated to use readMpObjName which tries
the plain-file path first, falling back to the meta storer.

Jira: CDM-557245
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
CompleteMultipartUpload no longer re-reads the whole object. validateRevealMpu
verifies each part against its stored ETag and accumulates the full-object
CRC64NVME from per-part CRCs recorded during UploadPart (new otterMpuPart.CRC),
so Complete is O(parts) not O(bytes) — fixes the ~16 min / 100 GiB stall that
exceeded the S3 client timeout.

Restore fsync durability, now that the SDFS RS-sync regression (CDM-550864,
reverted by scaledata/sdmain#226685) is fixed:
- writeAtomic → writeDurableAtomic: fsync temp fd + parent dir
- uploadPartAtOffset: tf.Sync() before index commit
- completeMultipartAtOffset: df.Sync() after each stash fold
- PutObject: f.Sync() postprocess hook before commit link

Jira: CDM-557245
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant