mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
fix(fuse): keep an upload pending until its bytes are cached (B119)
The drain retired an upload's op first, and only then read the node back and linked the staged blob into the content cache. For that one round trip, the status reported an empty queue for a file that wasn't cached yet, so anything that waited for an empty queue before reading the file could still need the network. The account run of 2026-10-03 hit it over a slow link: "regression B119" failed in the same second the upload landed. `Core::landing_uploads` now counts an upload from just before its op is retired until its bytes are cached. The status adds it to `pending_uploads`, and reads the queue before the count, so it always sees the upload in one of them. A drop guard uncounts it on every exit path. The op still goes first. An op restored after a crash would re-send a revision this daemon hasn't recorded as its own yet, and `revision_conflict` would keep it as a conflict copy of the user's file.
This commit is contained in:
1 parent
e32959e40a
commit
8d92c69279
5 files changed
+92
-6
No files matched your search
+21
-4
@@ -75,7 +75,8 @@ offline catches this race, and B117, if either comes back.
|
||||
|
||||
## B119 — Reading a file just written through the mount needs the network
|
||||
|
||||
**Status:** Fixed (verified 2026-10-03: "regression B119" passed in My files on the account run).
|
||||
**Status:** Fixed (unverified since the second fix below; "regression B119" passed on one account
|
||||
run of 2026-10-03 and failed on the next).
|
||||
**Found:** 2026-10-02, by the account run on flaky Wi-Fi, which crashed at its very end. The
|
||||
run's last step reads back a file it wrote to compare digests. The Wi-Fi had dropped, the read
|
||||
waited for `open_revision` for 120 seconds and then failed with `EIO`, and the suite stopped with
|
||||
@@ -96,9 +97,25 @@ discarded unless it is pinned, so one large upload cannot push the rest of the c
|
||||
is kept when the read-back fails or reports a different size. The suite records a failed end-of-run
|
||||
read-back as a failed check instead of crashing.
|
||||
|
||||
**Test:** the drain test `a_landed_upload_stays_cached_unless_it_would_crowd_the_cache_out`, and
|
||||
the acceptance case "regression B119", which writes two files, waits for the queue and expects
|
||||
`pdfs ls` to list both as cached.
|
||||
**Found again** on 2026-10-03, by "regression B119" on an account run over a slow link (uploads of
|
||||
a few bytes took 1.4 seconds). The case failed with "block.bin not cached after the upload" at the
|
||||
same second the journal logged that upload as landed.
|
||||
|
||||
**Cause, second part.** The drain retired the op first, and only then read the node back and
|
||||
linked the blob into the cache. For that one round trip the status reported an empty queue for a
|
||||
file that was not yet cached. Anything that waits for an empty queue before reading could still
|
||||
need the network.
|
||||
|
||||
**Fix, second part.** `Core::landing_uploads` counts an upload from just before its op is retired
|
||||
until its bytes are cached, and the status adds it to `pending_uploads`. The status reads the
|
||||
queue before the count, so it always sees the upload in one of them. The op still goes first: an
|
||||
op restored after a crash would re-send a revision this daemon has not yet recorded as its own,
|
||||
and `revision_conflict` would keep it as a conflict copy.
|
||||
|
||||
**Test:** the drain tests `a_landed_upload_stays_cached_unless_it_would_crowd_the_cache_out` and
|
||||
`a_landing_upload_counts_until_its_guard_goes`, `a_landed_upload_stays_pending_until_its_bytes_are_cached`
|
||||
in `lib.rs`, and the acceptance case "regression B119", which writes two files, waits for the
|
||||
queue and expects `pdfs ls` to list both as cached.
|
||||
|
||||
## B118 — Creating a file or folder through the mount can fail with `ENOENT` although it was made
|
||||
|
||||
|
||||
Reference in new issue
Block a user