mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-06 03:59:14 +00:00
b9b2aa0b76
A completed multipart upload's staging cleanup prunes empty parent directories up to the volume root, which removes shared prefixes such as `data-movement/` and the per-object `<sha>/` while a concurrent new_multipart_upload builds its destination chain below them. The writer holds a descriptor to the pruned component, so its next handle-relative mkdirat fails NotFound. Because rename never retried NotFound, the cleanup fan-out failed several disks in the same window and broke write quorum. Give rename preparation its own retry rule: a NotFound is retried once per component below the base directory, so a rebuilt walk outlasts a pruning walk, which removes ancestors monotonically upward and stops at the base. A destination whose parent is the base keeps NotFound terminal, so speculative cleanup renames still fail fast, and the base is only ever opened, never created, so a genuinely missing base still fails. The rename itself keeps its own budget and its unchanged NotFound-is-terminal rule.