mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 16:56:59 +01:00
chore(docs) updated changelog + bug states
This commit is contained in:
1 parent
78dc72a34d
commit
326a9b4e92
2 files changed
+136
-9
No files matched your search
+123
-9
@@ -12,13 +12,52 @@ Conventions:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## B86 — An on-demand mount serves a listing that predates the mirror engine's own uploads
|
||||||
|
|
||||||
|
**Status:** Open, live-reproduced 2026-08-16 on 1.8.1.
|
||||||
|
**Found:** 2026-08-16, while trying to drive B42's remote-delete path from one machine.
|
||||||
|
**Where:** `crates/pdfs-fuse/src/sync.rs` upload path (no listing invalidation) meets the cached
|
||||||
|
children snapshot the on-demand mount enumerates from.
|
||||||
|
|
||||||
|
**Repro.** With folder 6 (`~/pdfs-live-mirror`) in mirror mode: create `c1.txt` and `c2.txt`,
|
||||||
|
`pdfs sync now 6` — the activity feed reports `c1.txt new file`, `c2.txt new file` and
|
||||||
|
`sync_entry` gains rows carrying real `remote_uid`s. Switch the folder to on-demand and list it:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ls ~/pdfs-live-mirror
|
||||||
|
b25.txt
|
||||||
|
b40.bin # c1.txt, c2.txt and the conflict copy are missing
|
||||||
|
```
|
||||||
|
|
||||||
|
`ls ~/pdfs-live-mirror/c1.txt` returns `ENOENT`. Restarting the daemon does not help — the stale
|
||||||
|
children snapshot is in the database, not in memory. Switching the folder back to mirror proves
|
||||||
|
the files were on the server the whole time: the pass downloads all five, and `b40.bin` comes back
|
||||||
|
md5-identical.
|
||||||
|
|
||||||
|
**Effect.** No data loss — the mirror side is correct and the files are intact remotely — but a
|
||||||
|
user who switches a synced folder to on-demand sees an incomplete folder, and anything that walks
|
||||||
|
it (a backup, an indexer, `rm -r`) sees the same incomplete folder. It also blocks B42's live
|
||||||
|
verification, because `pdfs rm` cannot name a file the mount will not admit exists.
|
||||||
|
|
||||||
|
**Second, smaller gap in the same repro:** `pdfs refresh` and `pdfs ls` reject any path that is
|
||||||
|
not under the *primary* mountpoint (`Error: … is not under the mountpoint`), so a secondary
|
||||||
|
on-demand mount has no manual escape hatch either.
|
||||||
|
|
||||||
|
**Required fix/test:** invalidate (or update) the parent's cached children when the sync engine
|
||||||
|
creates a remote node, the same way the FUSE write path does; and let `refresh`/`ls` resolve a
|
||||||
|
path under any mount the daemon owns, not just the primary. Test: the repro above, asserting the
|
||||||
|
new files appear immediately after the mode switch.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## B84 — A block read that comes back short truncates the file, silently
|
## B84 — A block read that comes back short truncates the file, silently
|
||||||
|
|
||||||
**Status:** Fixed and **live-verified 2026-08-16**. **Data correctness** — an application reading a large
|
**Status:** Fixed and **live-verified 2026-08-16**. **Data correctness** — an application reading a large
|
||||||
file through the mount could get a truncated copy that reported success. The truncation is now
|
file through the mount could get a truncated copy that reported success. The truncation is now
|
||||||
impossible: a disagreement is repaired from the whole-file download, or the read fails `EIO`.
|
impossible: a disagreement is repaired from the whole-file download, or the read fails `EIO`.
|
||||||
Unverified because the repair path has not yet been driven against the three known files on a
|
Re-verified on 1.8.1 after the release build: `118454731_p0.png`, `121677947_p0.png`,
|
||||||
live mount, and the metadata question below is still open.
|
`123349685_p0.png` and `128451683_p0.png` each delivered exactly their `stat` size
|
||||||
|
(19471492, 11811519, 22055175, 11393178 bytes) with no `Invalid argument` reply in the journal.
|
||||||
**Found:** 2026-08-16, chasing what looked like log noise. GNOME's file indexer
|
**Found:** 2026-08-16, chasing what looked like log noise. GNOME's file indexer
|
||||||
(`localsearch-3`) was filling the journal with `libpng error: Read Error`,
|
(`localsearch-3`) was filling the journal with `libpng error: Read Error`,
|
||||||
`libpng error: IDAT: CRC error` and `File too small to be a PNG` on files under
|
`libpng error: IDAT: CRC error` and `File too small to be a PNG` on files under
|
||||||
@@ -1795,8 +1834,16 @@ suite run against a heavily loaded drain.
|
|||||||
|
|
||||||
## B25 — Weak Conflict Baseline Detection `(mtime, size)` (HIGH-05)
|
## B25 — Weak Conflict Baseline Detection `(mtime, size)` (HIGH-05)
|
||||||
|
|
||||||
**Status:** Fixed (unverified) 2026-08-16 — the FUSE-write half was closed by **B69**; the
|
**Status:** Fixed and **live-verified 2026-08-16** on 1.8.1 — the FUSE-write half was closed by
|
||||||
mirror half is closed here.
|
**B69**; the mirror half is closed here.
|
||||||
|
|
||||||
|
**Live verification (2026-08-16, `~/pdfs-live-mirror`, folder 6).** `b25.txt` was written with
|
||||||
|
mtime `12:00:10.100000000`, synced (baseline `local_mtime=1786874410`,
|
||||||
|
`local_mtime_ns=1786874410100000000`), then rewritten with sixteen different bytes and stamped
|
||||||
|
`12:00:10.900000000` — identical whole second, identical length. The next pass classified it as
|
||||||
|
locally changed and uploaded `b25.txt new version`; the baseline advanced to
|
||||||
|
`…410900000000`, and reading the file back through an on-demand mount of the same folder returned
|
||||||
|
`BBBBBBBBBBBBBBBB`. Under the old whole-second comparison this edit was invisible.
|
||||||
**Found:** 2026-07-21, multi-agent sync engine audit (`audit_bugs.md` HIGH-05)
|
**Found:** 2026-07-21, multi-agent sync engine audit (`audit_bugs.md` HIGH-05)
|
||||||
**Where:** `crates/pdfs-core/src/cache.rs:L157`, `Baseline`
|
**Where:** `crates/pdfs-core/src/cache.rs:L157`, `Baseline`
|
||||||
|
|
||||||
@@ -1961,7 +2008,15 @@ that made these look like incidents in the journal.
|
|||||||
|
|
||||||
## B32 — Race Condition in Concurrent Handle Release and Open (MED-05)
|
## B32 — Race Condition in Concurrent Handle Release and Open (MED-05)
|
||||||
|
|
||||||
**Status:** Fixed (unverified) 2026-08-16
|
**Status:** Fixed and **live-verified 2026-08-16** on 1.8.1
|
||||||
|
|
||||||
|
**Live verification (2026-08-16).** Three 64 MiB random files were written over the same mount
|
||||||
|
path (`ProtonDrive/pdfs-live-20260816/b32.bin`) back to back, each `cp` closing before the next
|
||||||
|
began, while the drain was still working. The queue coalesced them into a single op (29 queued =
|
||||||
|
28 known-stuck + 1). After the drain retired it, `pdfs refresh` dropped the cached listing and a
|
||||||
|
full re-read from Drive returned `4ad41482f5199a401e425381d7621626` — the md5 of the *third*
|
||||||
|
write, byte for byte. No open re-used a stale staged base, and the retry warning never had to
|
||||||
|
fire.
|
||||||
**Found:** 2026-07-21, multi-agent concurrency audit (`audit_bugs.md` MED-05)
|
**Found:** 2026-07-21, multi-agent concurrency audit (`audit_bugs.md` MED-05)
|
||||||
**Where:** `crates/pdfs-fuse/src/lib.rs:L4042, L4574`
|
**Where:** `crates/pdfs-fuse/src/lib.rs:L4042, L4574`
|
||||||
|
|
||||||
@@ -2101,7 +2156,22 @@ pass from being treated as successfully settled.
|
|||||||
|
|
||||||
## B39 — Sync Download Can Overwrite a Concurrent Local Edit (HIGH-09)
|
## B39 — Sync Download Can Overwrite a Concurrent Local Edit (HIGH-09)
|
||||||
|
|
||||||
**Status:** Fixed (unverified) 2026-08-16
|
**Status:** Fixed and **live-verified 2026-08-16** on 1.8.1
|
||||||
|
|
||||||
|
**Live verification (2026-08-16).** Folder 6 was switched to on-demand (evicting its local
|
||||||
|
copies) and then back to mirror, which queues a download of the 128 MiB `b40.bin`. Three seconds
|
||||||
|
into that download, `RACING-LOCAL-EDIT-B39` was written to the destination path. The pass logged
|
||||||
|
|
||||||
|
```
|
||||||
|
WARN pdfs_fuse::sync: sync: local file changed while downloading; keeping it as a conflict copy
|
||||||
|
path=/home/narl/pdfs-live-mirror/b40.bin expected=None
|
||||||
|
actual=Some(LocalSig { mtime: 1786916720, mtime_ns: Some(1786916720414151922), size: 21 })
|
||||||
|
```
|
||||||
|
|
||||||
|
and finished with the remote copy at `b40.bin` and the racing 21 bytes intact at
|
||||||
|
`b40 (sync-conflict 1786916794).bin` — which the following pass then uploaded as a file of its
|
||||||
|
own. Before the fix the rename would have destroyed those bytes with no trace.
|
||||||
|
|
||||||
**Found:** 2026-07-22, sync concurrency audit
|
**Found:** 2026-07-22, sync concurrency audit
|
||||||
**Where:** `crates/pdfs-fuse/src/sync.rs`, download classification and apply path
|
**Where:** `crates/pdfs-fuse/src/sync.rs`, download classification and apply path
|
||||||
|
|
||||||
@@ -2136,7 +2206,25 @@ the guard directly instead.
|
|||||||
|
|
||||||
## B40 — Sync Upload Can Stream Torn Live Content (HIGH-10)
|
## B40 — Sync Upload Can Stream Torn Live Content (HIGH-10)
|
||||||
|
|
||||||
**Status:** Fixed (unverified) 2026-08-16
|
**Status:** Fixed and **live-verified 2026-08-16** on 1.8.1
|
||||||
|
|
||||||
|
**Live verification (2026-08-16).** A 128 MiB `b40.bin` was dropped into folder 6 and a pass
|
||||||
|
forced; six seconds into the upload, sixteen bytes were overwritten at offset 100,000,000. The
|
||||||
|
pass logged
|
||||||
|
|
||||||
|
```
|
||||||
|
WARN pdfs_fuse::sync: sync: file changed while uploading; the remote revision may be torn and
|
||||||
|
will be replaced on the next pass rel="b40.bin"
|
||||||
|
streamed=LocalSig { mtime: 1786916599, mtime_ns: Some(1786916599336211782), size: 134217728 }
|
||||||
|
now=Some(LocalSig { mtime: 1786916605, mtime_ns: Some(1786916605686365985), size: 134217728 })
|
||||||
|
```
|
||||||
|
|
||||||
|
and — this is the part that matters — recorded the baseline against the *streamed* signature
|
||||||
|
(`…599`), not the file on disk. The very next pass therefore read the file as locally changed and
|
||||||
|
uploaded `b40.bin new version`. Round-tripping the folder through on-demand and back later
|
||||||
|
downloaded the remote copy at md5 `cfb45003003fb2ad50c2c365f8313849` — the post-mutation local
|
||||||
|
content, exactly. The torn revision healed itself without anyone asking.
|
||||||
|
|
||||||
**Found:** 2026-07-22, sync concurrency audit
|
**Found:** 2026-07-22, sync concurrency audit
|
||||||
**Where:** `crates/pdfs-fuse/src/sync.rs`, upload apply and baseline update
|
**Where:** `crates/pdfs-fuse/src/sync.rs`, upload apply and baseline update
|
||||||
|
|
||||||
@@ -2227,11 +2315,29 @@ the state the engine was asking for. Covered by
|
|||||||
`sync::tests::an_already_absent_path_counts_as_removed`. Unverified because no live sync pass has
|
`sync::tests::an_already_absent_path_counts_as_removed`. Unverified because no live sync pass has
|
||||||
been driven over an externally-deleted file yet.
|
been driven over an externally-deleted file yet.
|
||||||
|
|
||||||
|
**Live verification attempted 2026-08-16, blocked.** Driving this needs the *remote* side of a
|
||||||
|
mirror folder to lose a file, and a mirror folder's remote lives in the device share, which no
|
||||||
|
mountpoint exposes — `pdfs rm` only accepts paths under a mountpoint, and the obvious workaround
|
||||||
|
(switch the folder to on-demand, trash the file through its own mount, switch back) runs into
|
||||||
|
**B86**: the on-demand mount serves a listing that predates the mirror engine's uploads, so the
|
||||||
|
file to be trashed is not visible to `rm` at all. Verifying B42 live therefore needs either a
|
||||||
|
second client on the account or B86 fixed first. The ENOENT branch remains covered only by its
|
||||||
|
unit test.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## B43 — FUSE Directory Cookies Are Not Stable (MED-09)
|
## B43 — FUSE Directory Cookies Are Not Stable (MED-09)
|
||||||
|
|
||||||
**Status:** Fixed (unverified) 2026-08-16
|
**Status:** Fixed and **live-verified 2026-08-16** on 1.8.1
|
||||||
|
|
||||||
|
**Live verification (2026-08-16).** A probe opened
|
||||||
|
`ProtonDrive/pdfs-live-20260816` (12 files) and called `getdents64` with a 160-byte buffer, so the
|
||||||
|
kernel had to page through the listing; between every page it created a new file in the directory
|
||||||
|
and unlinked an older one. Three pages, 14 entries returned (12 + `.` + `..`), zero duplicates,
|
||||||
|
zero pre-existing entries missed — and none of the files created mid-enumeration appeared, which
|
||||||
|
is the frozen snapshot behaving as specified. The same probe against the pre-fix index-cookie
|
||||||
|
readdir is what this entry was written about.
|
||||||
|
|
||||||
**Found:** 2026-07-22, FUSE/POSIX audit
|
**Found:** 2026-07-22, FUSE/POSIX audit
|
||||||
**Where:** `crates/pdfs-fuse/src/filesystem.rs`, `ProtonFs::serve_readdir`
|
**Where:** `crates/pdfs-fuse/src/filesystem.rs`, `ProtonFs::serve_readdir`
|
||||||
|
|
||||||
@@ -2267,7 +2373,15 @@ entries between `getdents` calls, asserting no entry is skipped or repeated.
|
|||||||
|
|
||||||
## B44 — FUSE Background Workers Have No Coordinated Shutdown (MED-10)
|
## B44 — FUSE Background Workers Have No Coordinated Shutdown (MED-10)
|
||||||
|
|
||||||
**Status:** Fixed (unverified) 2026-08-16
|
**Status:** Fixed and **live-verified 2026-08-16** on 1.8.1
|
||||||
|
|
||||||
|
**Live verification (2026-08-16).** `systemctl --user restart proton-drive.service` on a daemon
|
||||||
|
with six live mounts, a busy drain and 18.4 GiB staged: stop to `Stopped` took 110 ms, the journal
|
||||||
|
shows the six unmounts followed by `sync engine stopping` and `daemon stopping`, and systemd never
|
||||||
|
reached its SIGKILL timeout. The old PID was gone immediately, and the fresh daemon settled at 42
|
||||||
|
threads — the same count the outgoing one had, so no loop was left behind or spawned twice. A
|
||||||
|
second restart mid-session behaved identically.
|
||||||
|
|
||||||
**Found:** 2026-07-22, daemon lifecycle audit
|
**Found:** 2026-07-22, daemon lifecycle audit
|
||||||
**Where:** `crates/pdfs-fuse/src/mount.rs`, mount lifecycle; drain/index/sync loops
|
**Where:** `crates/pdfs-fuse/src/mount.rs`, mount lifecycle; drain/index/sync loops
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,19 @@ Schema: **28** — migration V28 adds `sync_entry.local_mtime_ns`.
|
|||||||
and the refusals for symlinks, hard links, device nodes and `chmod` are deliberate — Drive
|
and the refusals for symlinks, hard links, device nodes and `chmod` are deliberate — Drive
|
||||||
cannot represent them, and a local-only representation no other Proton client can read would
|
cannot represent them, and a local-only representation no other Proton client can read would
|
||||||
be worse than a clean refusal (B31).
|
be worse than a clean refusal (B31).
|
||||||
|
- Six of this release's fixes were then driven live against the installed 1.8.1 on a real
|
||||||
|
account: the same-second edit uploads (B25), three rapid rewrites of a 64 MiB file publish the
|
||||||
|
third one byte for byte (B32), a write racing a download survives as a conflict copy (B39), an
|
||||||
|
upload torn by a concurrent write heals itself on the following pass (B40), a `getdents64`
|
||||||
|
walk with a 160-byte buffer against a directory mutated between pages returns every entry
|
||||||
|
exactly once (B43), and a restart of a daemon with six mounts and a busy drain stops in 110 ms
|
||||||
|
and comes back at the same thread count (B44). B42 could not be driven from a single machine —
|
||||||
|
see B86 below.
|
||||||
|
- One new bug came out of the verification: an on-demand mount serves a folder listing that
|
||||||
|
predates the sync engine's own uploads, so files the mirror pass created are invisible until
|
||||||
|
the folder is switched back (`docs/BUGS.md` B86). Nothing is lost — they are on the server and
|
||||||
|
come back on the next mirror pass — but they cannot be seen or named while the folder is
|
||||||
|
on-demand, which is also what blocks B42's live verification.
|
||||||
|
|
||||||
## [1.8.0] — 2026-08-16
|
## [1.8.0] — 2026-08-16
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user