From b3c031881b38b4c95e2945c05537b6a681a096d9 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Thu, 1 Oct 2026 09:57:11 +0200 Subject: fix(node): an upload never replaces a file, nor shares a part with another MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A name an upload in flight will take is reserved; each upload writes its own `name..part`; the finished file is published by a hard link, which refuses an existing target, and takes the next free name if one appeared meanwhile — the last ack names it. Two members sending one name at once wrote one part and published it twice; a file copied in during an upload was replaced (F-09). Co-Authored-By: Claude Opus 5.5 --- docs/MESHBAY_DESIGN.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/MESHBAY_DESIGN.md b/docs/MESHBAY_DESIGN.md index f1473f0..609c751 100644 --- a/docs/MESHBAY_DESIGN.md +++ b/docs/MESHBAY_DESIGN.md @@ -1624,7 +1624,14 @@ Five protections, and they are the substance: - a **filename allowlist**; - **no overwrite** — a colliding name gets a free one. The check is `Path.exists()`, and `stat()` is itself case-insensitive on NTFS and exFAT, so this already holds - there; + there. A name an upload in flight will take counts as taken, since its file + is not on disk yet; each upload writes a `.part` of its own (`name..part`); + and the finished file is published by a hard link, which refuses an existing + target, so a file that appeared while the upload ran — the operator's, or + another group's upload into a shared folder — is never replaced: the upload + takes the next free name and its last acknowledgement says which. Where the + filesystem has no hard links (FAT, exFAT, some network shares) the existence + check and the rename are as close as it gets; - **strict chunk ordering**; - a **size cap** — 8 GB per file by default, and **the operator's to set** (`max_upload_gb` in node.toml, on the Node page, or `meshbay-node transfers -- cgit v1.2.3